Android toolbar doesn't expand when scrolling up - android

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

Related

CollapsingToolbarLayout collapses inconsistently on RecyclerView scroll

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.

Android CoordinatorLayout, Listview and fixed toolbar

I have a layout which has a toolbar in the top, followed by 2 toolbar sized bars under it and a listview below that. When someone scrolls on the listview, the 2 bars under the toolbar should scroll up and disappear under the toolbar.
I tried putting the app:layout_scrollFlags="scroll|enterAlways" only on those bars and not the toolbar but then they doesn't respond to scroll events.
If I put the same scrollFlags on the toolbar as well, they all respond but I want the toolbar to always display.
If I move the two bars above the toolbar, it works and only the two bars respond, but now the toolbar is below the bars and this is not the display I want.
Try putting the Toolbar you want to stay still at the top below your appBar. Your AppBar contains the views that you actually want to scroll, while the other one will be below it. Make sure to have your app bar have an elevation of 0dp or else it will go and be displayed above it (or change the elevation of your toolbar to be higher than the appbar). Also add the Height of the bar you want to stay at the top as the top margin of the appbar so it starts out below you view.
<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">
<!--Toolbars you want to move-->
<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:layout_marginTop="?attr/actionBarSize"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#android:color/holo_blue_light"
android:layout_gravity="bottom"
app:layout_scrollFlags="scroll|enterAlways"
/>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#android:color/holo_orange_light"
android:layout_gravity="bottom"
app:layout_scrollFlags="scroll|enterAlways"
app:elevation="2dp"
/>
</android.support.design.widget.AppBarLayout>
<!--Toolbar you don't want to move-->
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="top"
android:background="#color/wallet_bright_foreground_holo_light"
app:popupTheme="#style/AppTheme.PopupOverlay"
/>
<!--Your content here -->
<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/item_list" />
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>

Android AppBarLayout + CollapsingToolbarLayout + CoordinatorLayout

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.

Pin TabLayout to top while Toolbar below scrolls into it using AppBarLayout

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.

Why do I get an extra 50 pixels of vscrolling on my AppBarLayout with scroll|enterAlways?

I have the following layout (almost the same as the scrollingActivity generated by Android Studio )
Notice the layout_heights and layout_scrollFlags
<?xml version="1.0" encoding="utf-8"?>
<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="com.man.myapplication.ScrollingActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="#dimen/app_bar_height"
android:background="#android:color/holo_red_dark"
android:fitsSystemWindows="true"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_green_dark"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|enterAlways">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#android:color/holo_blue_dark"
app:layout_collapseMode="pin"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_scrolling" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email"
app:layout_anchor="#id/app_bar"
app:layout_anchorGravity="bottom|end" />
</android.support.design.widget.CoordinatorLayout>
Problem
After starting the application, the CollapsingToolbarLayout doesn't start from below the statusbar, but from behind it and it still can be scrolled down 50 pixels.
(Notice in the gif below in the first view as I start the app)
+ sometimes it snaps below the header (where it should be) when playing with scroll.
Note: this does not appear with the exitUntilCollapsed flag
Question
Is there any way to get rid of that 50 extra pixels scroll and make the Toolbar appear properly under the statusbar?
(currently am debugging the design-support library)
Ok I've found a way to get rid of the extra scroll (though not an explanation for why it is happening):
Quickfix
Changing the android:fitsSystemWindows on the AppBarLayout to false gets rid of the extra scroll.
What happens
This setting makes the AppBarLayout begin its layout from the very top of the screen instead from below the statusbar, which somehow gets rid of the weirdscroll.
Note
Though this way your Toolbar won't be hidden nicely below the statusbar.
Result
Footnotes
What is still a mistery, is why doesn't the above behavior take into consideration the statusbar and adds that extra scrollheight. in its original form.

Categories

Resources