Search code examples
androidandroid-toolbarandroid-appbarlayout

Toolbar expands on swipe down


In my application I have a collapsing Toolbar. If I start a specific Fragment I want to collapse the Toolbar so it behaves like a "normal" one and that the user can not expend it by himself. Here is my layout which I use for my Toolbar:

<android.support.design.widget.AppBarLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/appBarLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <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:expandedTitleMarginEnd="64dp"
        app:expandedTitleMarginStart="48dp"
        app:titleEnabled="false"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <ImageView
            android:src="@drawable/drawer_background"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
            android:layout_width="match_parent"
            android:layout_height="172dp"
            android:scaleType="centerCrop"
            app:layout_collapseMode="parallax"
            android:minHeight="100dp" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolBar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="scroll|enterAlways" />

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

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

I also can collapse the layout from code like so:

appBarLayout.setExpanded(false, false);

final AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
params.setScrollFlags(0);
collapsingToolbarLayout.setLayoutParams(params);

But this does not help. If the user swipes down from the Toolbar it will expand.

Do you have any ideas why?


Solution

  • The core problem is that there is no CollapsingToolbarLayout.lock(); method up until now (v23.2.1 of support design). Hopefully, this feature will be included in a future version. Until then, I'm suggesting the following workaround:

    You can collapse and lock your toolbar with:

    appbar.setExpanded(false,false);
    CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)appbar.getLayoutParams();
    lp.height = (int) getResources().getDimension(R.dimen.toolbar_height);
    

    and unlock it with:

     CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)appbar.getLayoutParams();
     lp.height = (int) getResources().getDimension(R.dimen.nav_header_height);
    

    However, with the above code a problem occurs:

    when forcefully collapsing CoordinatorLayout the title of our Toolbar is gone and CollapsingToolbarLayout.setTitle(CharSequence title); no longer works. To fix that we add a TextView in our Toolbar and manipulate its visibility accordingly. (we want it "gone" in a fragment that has its toolbar 'unlocked' and "visible" in a fragment that has its toolbar 'locked'.

    We have to set TextView's android:textAppearance to be the same with CollapsingToolbarLayout's app:collapsedTitleTextAppearance to be consistent and avoid disrupting the user with different toolbar text sizes and colors.

    In summary, with an interface like this:

    public interface ToolbarManipulation {
        void collapseToolbar();
        void expandToolbar();
        void setTitle(String s);
    }
    

    implemantations like these:

    @Override
        public void collapseToolbar(){
            appbar.setExpanded(false,false);
            CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)appbar.getLayoutParams();
            lp.height = (int) getResources().getDimension(R.dimen.toolbar_height);
            toolbarCollapsedTitle.setVisibility(View.VISIBLE);
        }
    
        @Override
        public void expandToolbar() {
            CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)appbar.getLayoutParams();
            lp.height = (int) getResources().getDimension(R.dimen.nav_header_height);
            toolbarCollapsedTitle.setVisibility(View.GONE);
        }
    
        @Override
        public void setTitle(String s) {
            collapsingToolbarLayout.setTitle(s);
            toolbarCollapsedTitle.setText(s);
            collapsingToolbarLayout.invalidate();
            toolbarCollapsedTitle.invalidate();
        }
    

    and main xml like this:

    ....
      <android.support.design.widget.CollapsingToolbarLayout
                android:id="@+id/collapsing_toolbar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                app:contentScrim="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                app:collapsedTitleTextAppearance="@style/CollapsedAppBar"
    
                >
                    <android.support.v7.widget.Toolbar
                        android:id="@+id/toolbar"
                        android:layout_width="match_parent"
                        android:layout_height="?attr/actionBarSize"
                        android:background="?attr/colorPrimary"
                        app:layout_collapseMode="pin"
                        app:popupTheme="@style/AppTheme.PopupOverlay"
                        >
                        <TextView
                            android:layout_width="match_parent"
                            android:layout_height="?attr/actionBarSize"
                            android:visibility="gone"
                            android:layout_gravity="center_vertical|start"
                            android:gravity="center_vertical|start"
                            android:id="@+id/toolbar_collapsed_title"
                            android:textAppearance="@style/CollapsedAppBar"
                            />
                    </android.support.v7.widget.Toolbar>
            </android.support.design.widget.CollapsingToolbarLayout>
    ......
    

    you can lock and unlock your Toolbar as you like. Your fragments should call these functions in their onResume();

    I've uploaded an example implementation here.

    Note: This is just a workaround and obviously not the cleanest solution. We're waiting for a newer version of com.android.support to resolve this.