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.
Related
The application uses a CoordinatorLayout with a CollapsingToolbarLayout. Inside, below it is a RecyclerView with a ScrollingViewBehavior. Everything works correctly (AppBar collapses on scroll), but there is a problem:
If I swipe not the RecyclerView, but the AppBar area (from bottom to top), then the screen will only scroll until the AppBar collapses. For further scrolling, you need to swipe again.
There video for better understand the problem:
gif or video
My layout code:
<androidx.coordinatorlayout.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"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="400dp"
app:layout_scrollFlags="scroll|enterAlways"
app:title="#string/app_name" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F5F8FD"
android:orientation="vertical"
android:padding="5dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
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.
Hello I have CoordinatorLayout with AppBar, Toolbar and RecyclerView.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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="wrap_content"
android:elevation="0dp"
android:fitsSystemWindows="true"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="8dp"
android:fitsSystemWindows="true"
app:contentInsetEnd="0dp"
app:contentInsetStart="0dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_scrollFlags="scroll|exitUntilCollapsed"/>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_photos"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
I want to leave Toolbar on top and don't want to move it, but let LinearLayout scroll below it (under the Toolbar).
Also I found that RecyclerView's not working with Coordinator layout. It doesn't trigger AppBar scroll events. If I will wrap it inside NestedSCrollView it will work but RecyclerView's not recycling view holders then so it's doesn't work for me.
Could anyone help to achieve this?
try like this
...
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_photos"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</android.support.v4.widget.NestedScrollView>
Put your toolbar and linear layout in a CollapsingToolbarLayout. Then use appropriate collapse mode attributes. For example, you could use pin for your toolbar and parallax for your linear layout:
<android.support.design.widget.AppBarLayout>
<android.support.design.widget.CollapsingToolbarLayout
...
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
...
app:layout_collapseMode="pin"/>
<LinearLayout
...
app:layout_collapseMode="parallax"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
You need the dependency for design support library in your app's build.gradle:
implementation "com.android.support:design:$support_library_version"
More on coordinator and collapsing toolbar layouts
I couldn't implement it in the described way. RecyclerView doesn't send scroll events to AppaBar layout (what is really strange) so I need to split every view on that screen and make recycler view adapter handle them all in one recycler view. Thanks all for answers and time spent on this!
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 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