I have a Tablayout fragment with bottomnavigationview which contains three fragments. Each fragment has a recyclerview and a spinner in it. My tablayout fragment xml file is as follows
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null">
<!-- TODO: Update blank fragment layout -->
<RelativeLayout
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<CustomWidgets.LockableViewPager
android:id="@+id/stocksviewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:isScrollContainer="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</RelativeLayout>
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="?android:attr/windowBackground"
app:itemBackground="@color/bottomnavigationcolour"
app:itemIconTint="@drawable/bottomnav_colors"
app:itemTextColor="@drawable/bottomnav_colors"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_navigation_stocks" />
</android.support.constraint.ConstraintLayout>
The bottom navigation view pages has three fragments. Their layout is as follows
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/spinnerlayout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/spinners"
android:gravity="center"
android:background="#2e364c"
android:weightSum="2"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="5dp"
android:background="@drawable/spinner_background">
<Spinner
android:layout_width="match_parent"
android:layout_height="30dp"
android:dropDownVerticalOffset="30dp"
android:focusable="false"
android:id="@+id/indicesspinner"
android:entries="@array/indices_array" />
</LinearLayout>
<!--android:background="@drawable/spinner_background"-->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="5dp"
android:background="@drawable/spinner_background">
<Spinner
android:id="@+id/sortbyspinner"
android:layout_width="match_parent"
android:layout_height="30dp"
android:dropDownVerticalOffset="30dp"
android:entries="@array/sortby_array"/>
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:id="@+id/searchbar"
android:layout_below="@+id/spinners">
<AutoCompleteTextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:hint="Search Symbol"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/searchimage"
android:id="@+id/autocompletesearch"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/searchimage" />
<ImageView
android:layout_width="30dp"
android:layout_height="wrap_content"
android:id="@+id/searchimage"
android:tint="@color/white"
android:layout_alignParentRight="true"
android:src="@drawable/search_two"
android:layout_alignParentEnd="true" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_below="@+id/searchbar"
android:background="#4b88e2"
android:id="@+id/title">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:id="@+id/indexestitletv"
android:text="textview" />
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/indexesrefreshprogressbar"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
style="?android:attr/progressBarStyleSmall" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/rvrl"
android:layout_below="@+id/title" >
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/indexesrecyclerview" />
</RelativeLayout>
<!--<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:id="@+id/progressbar"
android:visibility="invisible"/>-->
</RelativeLayout>
</RelativeLayout>
Whenever I change the value from spinner and update recyclerview it shows me this error
java.lang.IllegalStateException: Circular dependencies cannot exist in RelativeLayout
at android.widget.RelativeLayout$DependencyGraph.getSortedViews(RelativeLayout.java:1724)
at android.widget.RelativeLayout.sortChildren(RelativeLayout.java:382)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:389)
at android.view.View.measure(View.java:18788)
at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:934)
at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:973)
at android.view.View.measure(View.java:18788)
at android.support.v7.widget.RecyclerView$LayoutManager.measureChildWithMargins(RecyclerView.java:8994)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1585)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1519)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:614)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3812)
at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3225)
at android.view.View.measure(View.java:18788)
at android.widget.RelativeLayout.measureChild(RelativeLayout.java:676)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:479)
at android.view.View.measure(View.java:18788)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
at android.view.View.measure(View.java:18788)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
at android.view.View.measure(View.java:18788)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1632)
at android.view.View.measure(View.java:18788)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
at android.view.View.measure(View.java:18788)
at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:934)
at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:973)
at android.view.View.measure(View.java:18788)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1632)
at android.view.View.measure(View.java:18788)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:739)
at android.support.design.widget.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:91)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1361)
at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:809)
at android.view.View.measure(View.java:18788)
at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1059)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:141)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget
However I cannot see any circular references in both layouts. Note that the same layout is working on Nougat and above. I cannot seem to understand what is causing this. This is my java class where i update the spinner and recyclerview
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_indexes, container, false);
indicesSpinner = rootView.findViewById(R.id.indicesspinner);
sortBySpinner = rootView.findViewById(R.id.sortbyspinner);
titleTextView = rootView.findViewById(R.id.indexestitletv);
indexFragmentCreated = true;
autoCompleteTextView = rootView.findViewById(R.id.autocompletesearch);
autoCompleteTextView.setThreshold(1);
autoCompleteTextView.setFocusable(true);
autoCompleteTextView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
ArrayAdapter<String> indicesAdapter = new ArrayAdapter<>(getContext(), R.layout.spinner_dropdown_view,
R.id.spinnerddtext, getResources().getStringArray(R.array.indices_array));
//indicesAdapter.setDropDownViewResource(R.layout.spinner_dropdown_view);
indicesSpinner.setAdapter(indicesAdapter);
indicesSpinner.setSelection(0);
indicesSpinner.setOnItemSelectedListener(this);
ArrayAdapter<String> sortbyAdapter = new ArrayAdapter<>(getContext(), R.layout.spinner_dropdown_view,
R.id.spinnerddtext, getResources().getStringArray(R.array.sortby_array));
//sortbyAdapter.setDropDownViewResource(R.layout.spinner_dropdown_view);
sortBySpinner.setAdapter(sortbyAdapter);
sortBySpinner.setSelection(0);
sortBySpinner.setOnItemSelectedListener(this);
indexesRecyclerView = rootView.findViewById(R.id.indexesrecyclerview);
indexesRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
refreshProgressBar = rootView.findViewById(R.id.indexesrefreshprogressbar);
refreshProgressBar.setVisibility(View.INVISIBLE);
/*indexesRecyclerView.addOnItemTouchListener(new RecyclerViewTouchListener(getContext(), indexesRecyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
Intent intent = new Intent(getContext(), SymbolStatsActivity.class);
startActivity(intent);
}
@Override
public void onLongClick(View view, int position) {
}
}));*/
progressBar = rootView.findViewById(R.id.progressbar);
//symbolDetailsHandler.postDelayed(symbolDetailsRunnable, AppConfig.symbolDetailsMaximumTimer);
//new GetAllSymbols().execute();
return rootView;
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (parent.getId()) {
case R.id.indicesspinner:
String selectedItem = parent.getItemAtPosition(position).toString();
switch (selectedItem) {
case "KSE 100": {
spinnerSelectedItem = "100Index";
sortBySpinner.setSelection(0);
titleTextView.setText(indicesSpinner.getSelectedItem().toString());
if (indexFragmentCreated) { //to prevent web request to be executed even when the user is not on screen
indexFragmentCreated = false;
return;
}
//stop continuously running handler
//symbolDetailsHandler.removeCallbacks(symbolDetailsRunnable);
//stop http request
if (myTask != null)
myTask.cancel(true);
if (checkDataInLocalDB()) {
startHandler();
}
else {
new GetIndexSymbols().execute();
}
/*//Retrieving stored list from sqlite
DatabaseHandler databaseHandler = new DatabaseHandler(getContext());
Cursor cursor = databaseHandler.getStocksSymbols(spinnerSelectedItem);
if (cursor != null && cursor.moveToFirst()) {
listSavedTime = cursor.getLong(0);
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<StocksBean>>() {}.getType();
stocksIndicesBeanList = new ArrayList<>();
stocksIndicesBeanList = gson.fromJson(cursor.getString(1), type);
Collections.sort(stocksIndicesBeanList, new Comparator<StocksBean>() {
@Override
public int compare(StocksBean stocksBean1, StocksBean stocksBean2) {
return stocksBean1.getSymbolCode().compareToIgnoreCase(stocksBean2.getSymbolCode());
}
});
adapter = new StocksRvAdapter(getContext(), stocksIndicesBeanList, "indexes");
indexesRecyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
symbolDetailsHandler.postDelayed(symbolDetailsRunnable, AppConfig.symbolDetailsMaximumTimer);
}
else {
myTask = new GetIndexSymbols().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, spinnerSelectedItem);
symbolDetailsHandler.postDelayed(symbolDetailsRunnable, AppConfig.symbolDetailsMaximumTimer);
}*/
break;
}
/*case "KSE All":
spinnerSelectedItem = "AllShr";
StocksRvAdapter allAdapter = new StocksRvAdapter(getContext(), Logs.scripListAll, null, "KSEALL");
indexesRecyclerView.setAdapter(allAdapter);
allAdapter.notifyDataSetChanged();
Toast.makeText(getContext(), Logs.scripListAll.size() + " items", Toast.LENGTH_LONG).show();
break;*/
case "KSE 30": {
spinnerSelectedItem = "30Index";
sortBySpinner.setSelection(0);
titleTextView.setText(indicesSpinner.getSelectedItem().toString());
//symbolDetailsHandler.removeCallbacks(symbolDetailsRunnable);
//myTask.cancel(true);
if (checkDataInLocalDB()) {
startHandler();
}
else {
new GetIndexSymbols().execute();
}
/*//Retrieving stored list from sqlite
DatabaseHandler databaseHandler = new DatabaseHandler(getContext());
Cursor cursor = databaseHandler.getStocksSymbols(spinnerSelectedItem);
if (cursor != null && cursor.moveToFirst()) {
listSavedTime = cursor.getLong(0);
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<StocksBean>>() {}.getType();
stocksIndicesBeanList = new ArrayList<>();
stocksIndicesBeanList = gson.fromJson(cursor.getString(1), type);
Collections.sort(stocksIndicesBeanList, new Comparator<StocksBean>() {
@Override
public int compare(StocksBean stocksBean1, StocksBean stocksBean2) {
return stocksBean1.getSymbolCode().compareToIgnoreCase(stocksBean2.getSymbolCode());
}
});
adapter = new StocksRvAdapter(getContext(), stocksIndicesBeanList, "indexes");
indexesRecyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
symbolDetailsHandler.postDelayed(symbolDetailsRunnable, AppConfig.symbolDetailsMaximumTimer);
}
else {
myTask = new GetIndexSymbols().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, spinnerSelectedItem);
symbolDetailsHandler.postDelayed(symbolDetailsRunnable, AppConfig.symbolDetailsMaximumTimer);
}*/
break;
}
case "KMI 30": {
spinnerSelectedItem = "KMI30Index";
sortBySpinner.setSelection(0);
titleTextView.setText(indicesSpinner.getSelectedItem().toString());
//symbolDetailsHandler.removeCallbacks(symbolDetailsRunnable);
//myTask.cancel(true);
if (checkDataInLocalDB()) {
startHandler();
}
else {
new GetIndexSymbols().execute();
}
}
}
}
public boolean checkDataInLocalDB() {
//Retrieving stored list from sqlite
DatabaseHandler databaseHandler = new DatabaseHandler(getContext());
Cursor cursor = databaseHandler.getStocksSymbols(spinnerSelectedItem);
if (cursor != null && cursor.moveToFirst()) {
listSavedTime = cursor.getLong(0);
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<StocksBean>>() {}.getType();
//stocksIndicesBeanList = new ArrayList<>();
stocksIndicesBeanList = gson.fromJson(cursor.getString(1), type);
Collections.sort(stocksIndicesBeanList, new Comparator<StocksBean>() {
@Override
public int compare(StocksBean stocksBean1, StocksBean stocksBean2) {
return stocksBean1.getSymbolCode().compareToIgnoreCase(stocksBean2.getSymbolCode());
}
});
adapter = new StocksRvAdapter(getContext(), stocksIndicesBeanList, "indexes");
indexesRecyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
return true;
}
else {
return false;
}
}
This is my build.gradle file
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion '26.0.3'
defaultConfig {
applicationId "com.example.abc"
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
//testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
//implementation 'com.android.support:support-v4:26.1.0'
compile fileTree(dir: 'libs', include: ['*.jar'])
/*androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})*/
compile 'com.android.support:appcompat-v7:26.1.0'
compile 'com.android.support:design:26.1.0'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.squareup.okhttp3:okhttp:3.10.0'
//for graphs
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.0'
testCompile 'junit:junit:4.12'
}
I am stuck on this. Any help will be greatly appreciated. Thank you.
EDIT1
Removed all relative layouts from screen. Still giving me circular dependency error in relative layout. Now this is pissing me off.
EDIT2
On further digging out, I found out that it is crashing in builtin class Recyclerview.java inside if condition at this line child.measure(widthSpec, heightSpec);. Don't know still what is causing this.
public void measureChildWithMargins(View child, int widthUsed, int heightUsed) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final Rect insets = mRecyclerView.getItemDecorInsetsForChild(child);
widthUsed += insets.left + insets.right;
heightUsed += insets.top + insets.bottom;
final int widthSpec = getChildMeasureSpec(getWidth(), getWidthMode(),
getPaddingLeft() + getPaddingRight()
+ lp.leftMargin + lp.rightMargin + widthUsed, lp.width,
canScrollHorizontally());
final int heightSpec = getChildMeasureSpec(getHeight(), getHeightMode(),
getPaddingTop() + getPaddingBottom()
+ lp.topMargin + lp.bottomMargin + heightUsed, lp.height,
canScrollVertically());
if (shouldMeasureChild(child, widthSpec, heightSpec, lp)) {
child.measure(widthSpec, heightSpec);
}
}