Miguel Ribeiro
Miguel Ribeiro

Reputation: 8184

Show view when toolbar collapses

I have an activity with a CoordinatorLayout, AppBarLayout, CollapsingToolbarLayout and Toolbar. So, basically, a view that collapses when scrolling a RecyclerView.

What I need to do is to show a custom view when the view of the expanded layout is hidden due to collapsing.

This is 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:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="192dp"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <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="#2196F3"
            app:expandedTitleMarginBottom="32dp"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <include
                android:id="@+id/header"
                layout="@layout/header_big_first_screen"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"/>

            <android.support.v7.widget.CollapsingToolbarLayout
                android:id="@+id/anim_toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

                <TextView

                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="Hello!"/>


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


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

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

    <android.support.v7.widget.RecyclerView
        android:id="@+id/categories_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>


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

In the end, when the toolbar is expanded the view loaded with the element is shown. When it is collapsed it doesn't . When it disappears the TextView inside Toolbarshould be shown. Currently it shows all the time.

I've been looking in the events of CollapsingToolbarLayout to add a listener when it changes size so I can check if that is smaller than a value and show that view.

This can be kind of tricky to explain but I believe I made myself clear. I've been googling around and cannot find anyone trying to do the same.

Upvotes: 26

Views: 19318

Answers (2)

0101100101
0101100101

Reputation: 5911

Instead of trying to replicate when the scrim is supposed to show (collapsed) or not (expanded), a better way is to override the setScrimsShown method, which is called every time inside the CollapsingToolbarLayout's onOffsetChanged, and add a listener to it like this:

public class CollapsingToolbarLayoutWithScrimListener extends CollapsingToolbarLayout {

    public CollapsingToolbarLayoutWithScrimListener(Context context) {
        super(context);
    }

    public CollapsingToolbarLayoutWithScrimListener(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CollapsingToolbarLayoutWithScrimListener(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context,attrs,defStyleAttr);
    }

    private ScrimListener scrimListener = null;

    @Override
    public void setScrimsShown(boolean shown, boolean animate) {
        super.setScrimsShown(shown, animate);
        if (scrimListener != null)
            scrimListener.onScrimShown(shown);
    }

    public void setScrimListener(ScrimListener listener) {
        scrimListener = listener;
    }

    public interface ScrimListener {

        void onScrimShown(boolean shown);
    }
}

Upvotes: 0

tachyonflux
tachyonflux

Reputation: 20221

Taking a look at the CollapsingToolbarLayout source, the content scrim animations are triggered via an OnOffsetChangedListener on the AppBarLayout. So you could add another one to trigger alpha animations on your text view:

mListener = new AppBarLayout.OnOffsetChangedListener() {
    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
        if(collapsingToolbar.getHeight() + verticalOffset < 2 * ViewCompat.getMinimumHeight(collapsingToolbar)) {
            hello.animate().alpha(1).setDuration(600);
        } else {
            hello.animate().alpha(0).setDuration(600);
        }
    }
};

appBar.addOnOffsetChangedListener(mListener);

Upvotes: 59

Related Questions