Show view when toolbar collapses
B

2

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.

Barbarity answered 23/7, 2015 at 18:48 Comment(2)
Could you just use the contentScrim?Partition
@karaokyo the setContentScrim and its variations are for drawables and colors only, unless I'm missing something . developer.android.com/reference/android/support/design/widget/…Barbarity
P
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);
Partition answered 24/7, 2015 at 4:19 Comment(5)
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 againBarbarity
It's the same trigger that the content scrim usesPartition
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.Hoppe
ViewCompat.getMinimumHeight returns 0 before API 16Tibia
Please, use collapsingToolbar.getScrimVisibleHeightTrigger() (developer.android.com/reference/android/support/design/widget/…) instead of (2 * ViewCompat.getMinimumHeight(collapsingToolbar)). It is more readable and also takes into account fitsSystemWindows flag inside.Encephalomyelitis
B
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);
    }
}
Benge answered 17/2, 2020 at 6:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.