0

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);
        }
    }
Coder
  • 21
  • 7

2 Answers2

0

You have unnecessarily placed RelativeLayouts inside RelativeLayout. Also, you don't need RelativeLayout when you are using ConstraintLayout.

Here is the reference link: circular-dependencies-cannot-exist-in-relativelayout-android

Faizan Mubasher
  • 4,427
  • 11
  • 45
  • 81
0

Ah finally i solved it. There was a line in my adapter xml android:layout_toRightOf="@+id/mainrl"

<View
    android:layout_width="2dp"
    android:layout_height="wrap_content"
    android:id="@+id/separatorend"
    android:background="#ebebeb"
    android:layout_toRightOf="@+id/mainrl"
    android:layout_alignBottom="@+id/mainseparator"
    android:layout_toStartOf="@+id/imagesrl"
    android:layout_toLeftOf="@+id/imagesrl"/>

Somehow it was not being detected in Nougat and above API's but on Marshmallow and below it was being detected by the system so making the crash. Removing this line solved the crash.

Coder
  • 21
  • 7