I have a CoordinatorLayout with an AppBarLayout to collapse/expand the Toolbar on scroll. The content view is a NestedScrollView with RecyclerViews (which scroll horizontally) and some other views without scrollviews. Pretty similar to the Airbnb app.
<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.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="#layout/toolbar_flat" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="#+id/newstedScrollView"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/consistentGreyWhite"
android:paddingBottom="#dimen/activity_vertical_margin"
android:clipToPadding="false"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/home_slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/consistentWhite"
android:clipToPadding="false"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="14dp"
android:paddingRight="14dp"
android:paddingTop="#dimen/activity_vertical_margin"
/>
<... other elements ...>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
If I scroll on an element without scrollviews the toolbar collapse/expand works. But if I perform a scroll (vertical) on a RecyclerView the toolbar doesn't work as expected. Seems like the RecyclerViews don't pass the scroll events to the CoordinatorLayout.
I too had this problem.
Add this property to your NestedScrollView tag
app:layout_behavior="#string/appbar_scrolling_view_behavior"
Also, do the following for each recyclerView object in your fragment or activity. And also in your adapter if you are nesting recycler_views'.
recyclerView.setNestedScrollingEnabled(false);
Add this property to your Recycler View.
app:layout_behavior="#string/appbar_scrolling_view_behavior"
Also you can add this to Recycler View.
mRecyclerView.setNestedScrollingEnabled(false);
Like this.
<android.support.v7.widget.RecyclerView
android:id="#+id/home_slider"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Also same thing for NestedScrollView with android:fillViewport="true".
You may use android:fillViewport="true" to make NestedScrollView measure the RecyclerView.
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
Related
So,
I have a layout.xml file which contains a Recycler View. Now, what I want is, I added two image Views on top of this Recycler View but I want those ImageViews to scroll with the RecyclerView as well.
I just wanted to ask, is this possible to do? And if yes, how can I achieve this?
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/content_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<include
android:id="#+id/header_bar"
layout="#layout/section_header" />
<ImageView-1>
<ImageView-2>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/category_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingHorizontal="#dimen/category_grid_edge_space"
android:paddingTop="#dimen/category_grid_padding_top"
android:scrollbarSize="#dimen/grid_padding"
android:scrollbarStyle="outsideOverlay"
android:scrollbarThumbVertical="?android:attr/textColorSecondary"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Put your RecycleView in NestedScrollView
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
layout="#layout/your_header"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/category_grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
also don't forget to disabled NestedScrolling for RecyclerView
myRecyclerView.setNestedScrollingEnabled(false);
OR
Add those views as a header. Here is a good guide on how to add a custom item view: https://medium.com/androiddevelopers/get-ahead-using-headers-in-recyclerview-2909a69b19
https://github.com/masudias/RecyclerView-with-Header-and-Footer
You can use header and footer i
I'm having a problem with Coordinatorlayout and ViewPager implementation.
In order to reproduce this you have to scroll down vigorously and while it's still happening try to scroll the list of items up - a sort of shaky stutter effect can be visible as if CoordinatorLayout was trying to scroll the view in separate direction than its child (RecyclerView).
You can view my layout here:
<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/mainContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<FrameLayout
android:id="#+id/headerContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="#+id/tabControl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorHeight="4dp"
app:tabMaxWidth="500dp">
</android.support.design.widget.TabLayout>
<LinearLayout
android:id="#+id/topLayout"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="vertical"
android:visibility="gone" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/tabContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Just to provide some further details:
headerContainer contains ConstraintLayout with some stuff like bunch of textviews, button - pretty usual.
tabContainer contains LinearLayout with list of items (recyclerview)
Add this to the recyclerView in the fragment of your ViewPager..
recyclerView.setNestedScrollingEnabled(false);
This is happening because of the app:layout_behavior="#string/appbar_scrolling_view_behavior" behavior of the viewpager.. this is causing the nestedScrolling.. that is why you feel the shaky effect..
Add this line to your RecyclerView
Recyclerview.setNestedScrollingEnabled(false);
View pager ScreenShot
Vertical View Pager
First Fragment
Second Fragment
Collapsing Toolbar
Image View
Tab Layout
View Pager
Grid Fragment
Second Fragment
Recycler View(Main)
Recycler View
Map Fragment
When i scroll (Main)recycler view Collapsing toolbar should expand and collapse and after vertical view pager should scroll.
But in my code (main)Recycler view not scrolling properly and collapsing toolbar not working properly.
Xml:
<android.support.design.widget.CoordinatorLayout
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/MyAppbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapse_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_collapseMode="none">
<TextView... />
<ProfileView... />
</LinearLayout>
<android.support.v7.widget.Toolbar
android:id="#+id/fragment_snip_details_2view"
android:layout_width="match_parent"
android:layout_height="#dimen/_40sdp"
android:background="#color/colorAccent"
android:minHeight="#dimen/_40sdp"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
<TabLayout...>
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="visible"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v4.view.ViewPager
android:id="#+id/fragment_snip_details_2_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
wrap your viewpager inside a NestedScrollView instead of a LinearLayout and then set the layout_behavior to appbar_scrolling_view for both the NestedScrollView and the ViewPager. Took me forever but I found that this worked for me.
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<com.example.ashleighwilson.schoolscheduler.views.CustomViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</com.example.ashleighwilson.schoolscheduler.views.CustomViewPager>
</android.support.v4.widget.NestedScrollView>
also be sure to set fillViewport to true in the NestedScrollView and make sure the width and height is set to match parent. This is important.
I want to hide/show the Toolbar when ListView is scrolling. I have CorrdinatorLayout with Toolbar included in. I add the app:layout_scrollFlags="scroll|enterAlways" attribute to the Toolbar. Then I have Listview inside content_min layout with RelativeLayout with app:layout_behavior="#string/appbar_scrolling_view_behavior" attribute. I included the content_main layout inside CoordinatorLayout -Toolbar not responsive to scroll events on listview. Does this Feature work with RecyclerView only and not listview?
<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.era.www.onmovie.MainActivity">
<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>
<include layout="#layout/content_main" />
content_main layout
<RelativeLayout 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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.era.www.onmovie.MainActivity"
tools:showIn="#layout/activity_main">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="#+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
The scrolling behavior works with RecyclerView but not out-of-box with ListView. This is because the scrolling behavior needs a scrolling component that implements the NestedScrollingChild interface. This interface is implemented by RecyclerView but not ListView.
My recommendation would be to convert your ListView adapter to a RecyclerView adapter and use RecyclerView.
Supposedly there are some ways to put a ListView inside a NestedScrollView which will give the scrolling behavior. I don't recommend this, but if you search SO you can find some solutions for wrapping your ListView inside a NestedScrollView and getting the toolbar to scroll.
I have 3 views in my layout file with CoordinatorLayout as the root view : AppbarLayout, RecyclerView and a Footer(not visible all the time). Recyclerview implements the default behavior appbar_scrolling_view_behavior, that ideally, brings recyclerview below the appbarlayout. But the recyclerview and footer overlap. To Prevent that, I had to write a custom behavior so that when footer is visible, Recyclerview should make space for the footer. But now, the default behavior of appbar_scrolling_view_behavior is gone and now appbarlayout and recyclerview overlap.Here is the Image of the layout
Link to the custom behavior i implemented:
https://github.com/Mandeep221/CustomBehaviorForRecyclerview/blob/master/CustomBehavior.java
My Question: How can i implement 2 things(simultaneously in one behavior):
get the recyclerview below the appbarlayout inside the co-ordinatorlayout
get the recycelerview to make space for the footer if the footer is visible.
If you can suggest some workaround, that would also be great! Thanks alot!
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways|snap" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/list_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="4dp"
android:scrollbars="vertical"
app:layout_behavior="prokure.it.prokure.Search.NewSearch.CustomBehavior" />
<prokure.it.prokure.FooterBarLayout
android:id="#+id/footerBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
//footer child views
</LinearLayout>
</prokure.it.prokure.FooterBarLayout>
</android.support.design.widget.CoordinatorLayout>
Don't keep the android.support.design.widget.CoordinatorLayout as root layout.
Add a RelativeLayout as a root layout. Then add android.support.design.widget.CoordinatorLayout with property layout_alignParentTop and layout_above="#+id/footerBar" and set prokure.it.prokure.FooterBarLayout as align parent bottom as second child of RelativeLayout.
<RelativeLayout
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.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_above="#+id/footerBar">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways|snap" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/list_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="4dp"
android:scrollbars="vertical"
/>
</android.support.design.widget.CoordinatorLayout>
<prokure.it.prokure.FooterBarLayout
android:id="#+id/footerBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
//footer child views
</LinearLayout>
</prokure.it.prokure.FooterBarLayout>
</RelativeLayout>
Another simpler way is to add following lines to your prokure.it.prokure.FooterBarLayout
app:layout_anchor="#id/list_recycler_view"
app:layout_anchorGravity="bottom"
and keep prokure.it.prokure.FooterBarLayout inside coordinator layout.
Make sure to add an empty cell at the end of the recycler view so that prokure.it.prokure.FooterBarLayout does not overlap with last cell of RecyclerView.