Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

requestLayout() improperly called by CollapsingToolbarLayout

I have a collapsing toolbar layout which contains an image and on collapse shows the toolbar title. I needed to change the toolbar title font so I added a textview inside toolbar layout. Now I'm getting the following error generated repeatedly whenever I collapse the toolbar.

08-12 13:14:19.604 2263-2263/com.panoroma.admin W/View: requestLayout() improperly called by android.support.design.widget.CollapsingToolbarLayout{2d353cd6 V.ED.... ........ 0,0-1080,390 #7f0c0070 app:id/collapsing_toolbar} during second layout pass: posting in next frame 
08-12 13:14:19.604 2263-2263/com.panoroma.admin W/View: requestLayout() improperly called by android.support.v7.widget.AppCompatTextView{1bb84b57 V.ED.... ........ 168,48-407,119 #7f0c0073 app:id/toolbar_title} during second layout pass: posting in next frame

my layout...

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed|exitUntilCollapsed">

        <ImageView
            android:id="@+id/header"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:adjustViewBounds="true"
            android:layout_gravity="center"
            android:scaleType="centerCrop"
            android:layout_marginTop="15dp"
            android:layout_marginBottom="15dp"
            android:background="@drawable/dashboard80"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.5"  />

        <android.support.v7.widget.Toolbar
            android:id="@+id/da_toolbar"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            app:layout_collapseMode="pin"
            android:layout_height="?attr/actionBarSize">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20sp"
                android:textColor="?attr/colorAccent"
                android:id="@+id/toolbar_title"/>

        </android.support.v7.widget.Toolbar>

    </android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>


<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/rel_dash_icon"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" >

.........................

</ScrollView>

</android.support.design.widget.CoordinatorLayout>

java file..

Typeface ubuntuC = Typeface.createFromAsset(getAssets(), "ubuntuC.ttf");
Toolbar toolbar = (Toolbar) findViewById(R.id.da_toolbar);
    toolbar.setTitle("");
    setSupportActionBar(toolbar);

    toolbar_title = (TextView)toolbar.findViewById(R.id.toolbar_title);
    toolbar_title.setTypeface(ubuntuC);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
        getSupportActionBar().setHomeAsUpIndicator(getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha, null));
    else
        getSupportActionBar().setHomeAsUpIndicator(getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha));
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    final CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
    AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar);
    appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        boolean isShow = false;
        int scrollRange = -1;

        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            if (scrollRange == -1) {
                scrollRange = appBarLayout.getTotalScrollRange();
            }
            if (scrollRange + verticalOffset == 0) {
//                    collapsingToolbarLayout.setTitle("Dashboard");
                toolbar_title.setText("Dashboard");
                isShow = true;
            } else if(isShow) {
//                    collapsingToolbarLayout.setTitle("");
                toolbar_title.setText("");
                isShow = false;
            }
        }
    });

I just want a toolbar with a center image which on collapse will display the title. Title will have custom font. Now, is there a better way doing this?

like image 363
Monalisa Guria Avatar asked Aug 12 '16 08:08

Monalisa Guria


4 Answers

Following piece of code worked for me added post Runnable on AppBarLayout

mAppBar.addOnOffsetChangedListener(new AppBarStateChangeListener() {
            @Override
            public void onStateChanged(AppBarLayout appBarLayout, final int state, int done) {
                mAppBar.post(new Runnable() {
                    @Override
                    public void run() {
                        if (state == COLLAPSED) {
                            mToolBarTitle.setText(model.getTitle());
                        } else if (state == EXPANDED || state == IDLE) {
                            mToolBarTitle.setText("");
                        }
                    }
                });
            }
        });
like image 165
silentsudo Avatar answered Oct 24 '22 23:10

silentsudo


onOffsetChanged() is called so many times and android is throwing that warning because you are requesting layout as part of toolbar_title.setText("Dashboard"); . What you should do is , use a boolean flag and call it only once if the condition is met or check the VISIBILITY flag for the toolbar text view ,something like this.

  1. Add textview inside your toolbar layout under CollapsingLayout

       < android.support.v7.widget.Toolbar
         android:id="@+id/toolbar"
         android:layout_width="match_parent"
         android:layout_height="?attr/actionBarSize"
         app:layout_collapseMode="pin"
         app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
    
             <TextView
                android:id="@+id/toolbar_title"
                style="@style/Toolbar.Title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:visibility="gone"
                android:layout_gravity="center" />
    
      </android.support.v7.widget.Toolbar>
    
  2. In your activity or fragment class inside OnOffsetChangedListener() modify some thing like below with check. This will stop the warnings.

    appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
      @Override
      public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
        if (verticalOffset == toolbar.getHeight() - collapsingToolbarLayout.getHeight()) {
    
          if (textView.getVisibility() != View.VISIBLE) {
            textView.setVisibility(View.VISIBLE);
            textView.setText(title); // show toolbar title
          }
        } else {
          if (textView.getVisibility() != View.GONE) {
            textView.setVisibility(View.GONE); // hide title bar
          }
        }
      }
    });
    

    }

like image 28
rana Avatar answered Oct 24 '22 23:10

rana


I had the same problem and this page gives me a hint : here

I removed the collapsingToolbarLayout.setTitle("Dashboard"); collapsingToolbarLayout.setTitle(" "); and created two styles in styles.xml:

<style name="CustomCollapsingCollapsed">
   <item name="android:textColor">@color/colorText</item>
</style>
<style name="CustomCollapsingExpanded">
  <item name="android:textColor">@color/transparent</item>
</style>

And use them in

<android.support.design.widget.CollapsingToolbarLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:contentScrim="@color/colorAccent"
   app:layout_scrollFlags="scroll|exitUntilCollapsed"
   app:expandedTitleTextAppearance="@style/CustomCollapsingExpanded"
   app:collapsedTitleTextAppearance="@style/CustomCollapsingCollapsed"
   >

No logs anymore... Hope it helps!

like image 37
DPalagi Avatar answered Oct 25 '22 00:10

DPalagi


You can actually set a title colour for collapsed and expanded mode which will transition between the two when the toolbar is collapsing.

In your case rather then manually handling the collapse/expansion and setting the title you could set the expanded title colour to transparent and the collapsed title colour to whatever you originally wanted it to be.

So now when expanded the toolbar title is invisible and when collapsed the toolbar title is visible.

like image 31
Christopher Komodromos Avatar answered Oct 25 '22 01:10

Christopher Komodromos