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
Related
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.
When adding scrolling behaviour to a layout with coordinatorLayout like this:
<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">
<android.support.design.widget.AppBarLayout
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"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/mainContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
the mainContent is the part that matters.
The real layout will be inflated inside this container.
Imagining my View consists of a RecyclerView, and a fixed layout at the bottom of the screen.
Does someone know a way to remove the scrolling behavior of the bottom fixed layout and keep the RecyclerView-Toolbar-hide behaviour?
Inside a 'CoordinatorLayout' the views that scroll must be first and only later the non-scrollable views. I managed to solve the issue by placing my non-scrollable layout outside the 'mainContent', just below it
I have a CoordinatorLayout, AppBarLayout, Toolbar and main content in the form of NestedScrollview and stuff inside it:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
>
</android.support.v7.widget.Toolbar>
</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:fitsSystemWindows="true"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world"
/>
</android.support.v4.widget.NestedScrollView>
In the picture above, the blue section is the NestedScrollView (i.e., the main content). As you see, its height is calculated with no regard to toolbar and is just moved out of the screen.
If you replace the CoordinatorLayout with any other layout, the NestedScrollView fits well (again, the blue part is the content, i.e., the NestedScrollView):
Is it how it should behave by design? If so, how to make the NestedScrollView fit the remaining screen wholly without moving its part below?
Update: If I remove behavior on the NestedScrollView, it moves back to top, but then gets covered by the toolbar.
Update 2: Sorry if it wasn't clear, but the main idea for using the CoordinatorLayout was the ability to apply various behaviors, including the default one provided. I have some user entered text that potentially may not fit into the screen, so I surround it with NestedScrollView. Now, to ease entering the text and have more space available, I'd want the toolbar to scroll out when scrolling and typing into this input (because adjustPan and adjustResize are not ideal)
Try surrounding it with the <LinearLayout> . I mean, after the Coordinate Layout.
Use weights attributes of LinearLayout ( If necessary ) .
Set Width and height of the Nestedscrollview as Match_parent or fill_parent.
Another thing, you actually don't want to worry about the issue you specified above. It should work well when you execute.
Here is the code with <LinearLayout> . Using this tag inside will give us flexible alignment. It may be difficult at first time , but use it and practice surely it will do a trick.
Here the NestedScrollView is fixed inside the screen.
<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"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/third"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world"
/>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
Its Pretty simple.You can try this in CoordinatorLayout.
<?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:id="#+id/parentlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity"
android:animateLayoutChanges="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="#dimen/margin_16"
app:expanded="true"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
<!-- Your Entire Code goes Here -->
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
Your View will look like this
In case anyone is still interested in this issue, I guess I have the explanation why this happens.
So the main issue here is the AppbarLayout and it's ability to add scrolling behaviours when it's used with a CoordinatorLayout. Let's say you want to scroll away the toolbar when a user scrolls down on the view below the AppbarLayout (Let's say you have a ViewPager). Then the OS also needs to scroll that ViewPager up to fill the space on the top of the screen. But when that happens if the ViewPager doesn't have enough height to fill the entire screen, then there would be a space on the bottom. That's why the system adds an additional height (which is exactly the same height as the AppbarLayout has) to the bottom of theViewPager, to fill the space on the top, in case the AppbarLayout scrolls away.
If you look at the problem in this way, this is something that needs to be done to have a consistent view. So either you have to remove the AppbarLayout or decide not to use scrolling behaviours.
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" />