26

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.

Miguel Ribeiro
  • 8,057
  • 20
  • 51
  • 74
  • Could you just use the contentScrim? – tachyonflux Jul 23 '15 at 19:12
  • @karaokyo the setContentScrim and its variations are for drawables and colors only, unless I'm missing something . https://developer.android.com/reference/android/support/design/widget/CollapsingToolbarLayout.html – Miguel Ribeiro Jul 23 '15 at 19:29

2 Answers2

59

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);
tachyonflux
  • 20,103
  • 7
  • 48
  • 67
  • Totally worked! Much thanks! Mind the question: I'm looking at that implementation of `CollapsibleToolbarLayout` but how did you got to the value `(2 * ViewCompat.getMinimumHeight(collapsingToolbar))`? Thanks again – Miguel Ribeiro Jul 24 '15 at 23:10
  • 3
    It's the same trigger that the content scrim uses – tachyonflux Jul 25 '15 at 01:00
  • Thanks for the solution @karaokyo Works like a charm! However while its alright for a mobile device, your if else cases don't get triggered on a tablet. Any idea why is that? Thank you. – Suleiman19 Sep 24 '15 at 13:45
  • 1
    ViewCompat.getMinimumHeight returns 0 before API 16 – Clive Jefferies Oct 05 '16 at 13:43
  • 4
    Please, use `collapsingToolbar.getScrimVisibleHeightTrigger()` (https://developer.android.com/reference/android/support/design/widget/CollapsingToolbarLayout.html#getScrimVisibleHeightTrigger()) instead of `(2 * ViewCompat.getMinimumHeight(collapsingToolbar))`. It is more readable and also takes into account `fitsSystemWindows` flag inside. – EgorD Feb 24 '17 at 01:27
0

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);
    }
}
0101100101
  • 5,786
  • 6
  • 31
  • 55