When using a CollapsingToolBarLayout with a RecyclerView, I found that the toolbar collapsed inconsistently when scrolling. I could scroll about halfway through the recyclerview before anything collapsed at all, and then it would collapse in fits and starts. The behavior wasn't always consistent - sometimes it would collapse more than others. By the time I scrolled to the bottom, however, it was always fully collapsed. My XML looked like the following:
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" >
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed" >
<com.google.android.material.appbar.MaterialToolbar
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
It turned out that the ultimate issue was having a second RecyclerView within some of the view holders of the first. As per this answer, setting setNestedScrollingEnabled(false) on the inner RecyclerView caused things to behave as expected.
Related
Here is my layout hierarquy
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:theme="#style/AppThemeAppBarOverlay"
app:elevation="0dp">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar_layout"
contentScrim="#color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
app:contentScrim="#color/transparent"
app:layout_scrollFlags="scroll|enterAlways">
<LinearLayout
android:id="#+id/openday_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical"
android:paddingTop="?attr/actionBarSize"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="1">
...</LinearLayout>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:clipChildren="false"
android:clipToPadding="false"
app:layout_collapseMode="pin"
app:layout_scrollFlags="snap|exitUntilCollapsed"
app:popupTheme="#style/AppThemePopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/card_view_margin_bt"
android:background="#color/windowBackground"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:listitem="#layout/card_item" />
</android.support.design.widget.CoordinatorLayout>
<include layout="#layout/navigation_view" />
I have two problems:
When the appbarLayout is expanded, and i perform a quick scroll Up in the recyclerView, the recyclerView scroll really fast and at the same time the collapsing toolbar start collapsing. This shouldnt happen. I want to only allow scroll in the recyclerView when the collapsingLayout is fully collapsed. I think the problem has to do with the recyclerView fling, because if i scroll it slow, this bug doesn't occur. I'm trying to find a workaround for this.
The second thing is, when the activity start, the appbar is expanded. i want it to start collapsed, which works with
appBarLayout.setExpanded(false, true)
But with this approach, the toolbar is also collapsed. I want to just collapse the appBarLayout header but not the toolbar.
The first issue is related to clipToPadding messing with the recyclerView scrolls. Just removed it and the glitch was gone.
The second issue was solved by removing all the toolbar flags and manually translating the view in the appBarLayout listener. Don't know if it is the best thing to do, but worked for me wonderfully.
I have a TabLayout that I want always pinned to the top, and a Toolbar below that, that when the view is scrolled, scrolls up into the TabLayout.
<android.support.design.widget.CoordinatorLayout
android:id="#+id/main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".main.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:animateLayoutChanges="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/imageView2"
android:src="#drawable/music_content"
android:contentDescription="#string/image_chooser_title"
/>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
You can see here that I've set the Toolbar
app:layout_scrollFlags="scroll|enterAlways"
and not set any scrolling flags for the TabLayout above, since I want it to remain pinned. However, using these settings, the AppBarLayout doesn't scroll at all. If I add a scroll flag to the TabLayout, then they both scroll, and the TabLayout doesn't remain fixed. Is there a way to have the TabLayout remain fixed, while the Toolbar below scrolls up "off screen?"
Pictures can be provided if needed
As per the Android Design Support Library blog post:
One note: all views using the scroll flag must be declared before views that do not use the flag. This ensures that all views exit from the top, leaving the fixed elements behind.
So what you want is not possible with AppBarLayout.
I have a layout (as generated by android studio) where i added a RelativeLayout to the AppBarLayout. The code is below and it looks like this:
Where i am stuck: What i want to achieve is when scrolling the Recyclerview down i want that the green relative layout (which has the id 'controlContainer') scrolls out with it, and when i scroll up it should scroll in (not just on the top but at any place i scroll up in the list)
The Toolbar on top should stay where it is.
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay"
/>
<RelativeLayout
android:id="#+id/controlContainer"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#android:color/holo_green_dark"
app:layout_scrollFlags="scroll|enterAlways"></RelativeLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<include layout="#layout/venue_list" />
</FrameLayout>
I thought that using app:layout_scrollFlags="scroll|enterAlways" in the view that should scroll away combined with app:layout_behavior="#string/appbar_scrolling_view_behavior"should achieve that, but it does not do anything. alternatively, when i add those fields to the toolbar itself both layouts scroll away - which is not what i want, i want the toolbar to stay always fixed.
would be nice if anyone could point me in the right direction here? (i hoped it would be possible with using coordinator layout and not hacking some layout manipulation with onscroll listeners?)
Try this in your toolbar code:
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
I found this link helpful: Scrolling Toolbar
I am trying to implement Google's newest design tricks with CoordinatorLayout and have problems with scrolling and parallax effect.
After Activity is displayed, everything looks ok but the problem occurs when I try to scroll. It seems the bottom View is not expanded correctly and after it's scrolled up, empty space appears below. Bottom View seems to be big only how much it has on initial display between top View and nav bar.
It looks something like this:
Relevant code:
<FrameLayout 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">
<CoordinatorLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:expandedTitleMarginStart="72dp"
app:expandedTitleMarginEnd="16dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_collapseMode="parallax"/>
</CollapsingToolbarLayout>
</AppBarLayout>
<ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</CoordinatorLayout>
</FrameLayout>
This weird behavior happens randomly. Sometimes bottom View is scrollable normally and that empty space doesn't appear. What am I doing wrong? Thanks.
I had the same problem and I noticed that every layout with this problem had
android:fitsSystemWindows="true"
on CoordinatorLayout
Removing it fixed my problem everywhere.
Try to add Toolbar inside yours CollapsingToolbarLayout:
<android.support.design.widget.CollapsingToolbarLayout>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
app:layout_collapseMode="pin"/>
...
</android.support.design.widget.CollapsingToolbarLayout>
Also try to add
android:minHeight="?attr/actionBarSize"
to Toolbar CollapsingToolbarLayout and AppBarLayout
For navigational flags reasons android:fitsSystemWindows="true" did not meet my needs.
After some playing around I found that adding another CollapsingToolbarLayout with 0dp hieght does the trick.
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_scrollFlags="scroll|snap" />
I have a toolbar that collapses when the RecyclerView scrolls down, but when the user scrolls up quickly, the toolbar doesn't expand. Any idea what is wrong?
This behavior is shown in this video: https://youtu.be/67ntPkW-5XA
Layout code :
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<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/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<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" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:clickable="true"
android:onClick="showText"
android:src="#drawable/ic_done_white_24dp"
app:borderWidth="0dp" />
If you want it to expand every time you scroll up, you should add app:layout_scrollFlags="scroll|enterAlways" to the view you want to be shown.
As I understand you want to add this to your CollapsingToolbarLayout.
Possible flags:
scroll: this flag should be set for all views that want to scroll off the screen - for views that do not use this flag, they’ll remain pinned to the top of the screen
enterAlways: this flag ensures that any downward scroll will cause this view to become visible, enabling the ‘quick return’ pattern
enterAlwaysCollapsed: When your view has declared a minHeight and you use this flag, your View will only enter at its minimum height (i.e., ‘collapsed’), only re-expanding to its full height when the scrolling view has reached it’s top.
exitUntilCollapsed: this flag causes the view to scroll off until it is ‘collapsed’ (its minHeight) before exiting