If i have such a configuration as shown below, like a custom View inside a CollapsingToolbarLayout with height more than a screen height, i cannot collapse it.
What for i need to do it? I need to have a content which will scroll up with a recyclerview below it. Without parallax or other effect, just scroll.
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/refresher"
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:background="#color/accent_material_light"
android:isScrollContainer="false">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
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"
android:fitsSystemWindows="true"
app:layout_collapseMode="pin"/>
<View android:layout_width="match_parent"
android:layout_height="1500dp"
android:background="#color/green_A100"
app:layout_scrollFlags="scroll"
/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycle_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/cardview_light_background"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</android.support.design.widget.CoordinatorLayout>
</android.support.v4.widget.SwipeRefreshLayout>
Per the Support Library 23.1 release blog post:
You’ll also find that AppBarLayout now allows users to start scrolling from within the AppBarLayout rather than only from within your scrollable view
If you'd like to start scrolling from within your AppBarLayout/CollapsingToolbarLayout, you'll want to update to at least version 23.1.0 of the Design Library.
Related
I am trying to implement pull to refresh but I'm having an issue with SwipeRefreshLayout not wrapping the child view's height. In the view preview and in a live build it appears to have 0 height.
The layout as as follows:
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
app:layout_collapseMode="pin">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="#layout/child_layout" />
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
I have also tried making the SwipeRefreshLayout the parent of the AppBarLayout without any success as well as putting a singular LinearLayout inside of the SwipeRefreshLayout. The only thing that seems to prevent the height of the swipe layout from being 0 is to set it statically but I want it to be dynamic based upon the height of the child view.
Is there something I'm missing here? It seems like there may be a bug with SwipeRefreshLayout because replacing it with a LinearLayout that also wraps the content works as expected.
The problem is your SwipeRefreshLayout is inside the Toolbar and AppBarLayout. You must wrap AppBarLayout with another layout and put SwipeRefreshLayout below the AppBarLayout. An example is at the below.
<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"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
tools:context="com.vsahin.moneycim.View.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="250dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark"
android:fitsSystemWindows="true"
app:expanded="false">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
android:fitsSystemWindows="true"
android:background="#drawable/gradient_background">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
if your SwipeRefreshLayout height is wrapping the content of your child_layout, then your child_layoutheight should be set to match_parent OR both SwipeRefreshLayout and child_layout height should be set to match_parent as shown in the Android Documentation
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Child View-->
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
SwipeRefreshLayout is a transparent View, so best solution to set it match_parent it will not conflict with other Views and don't include View or Layout within it, keep it clean
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
app:layout_collapseMode="pin">
<include layout="#layout/child_layout" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
SwipeRefreshLayout has to be in top to overlay other layers and be clickable
I am having issues with the expected scroll behavior of a collapsing toolbar layout within an app. To ensure I kinda knew what I was doing I created a simple test project and was able to achieve the desired result, but a NestedScrollView was used in that example and the content that required scrolling was just a RelativeLayout containing a CardView with a lot of text. In the real app the scroll content is a RecyclerView, which I assume is the problem. It is as if the RecyclerView is handling the scrolling and the parent CollapsingToolbar is left out of the loop.
Notice that the app:layout_behavior="#string/appbar_scrolling_view_behavior" is not currently in the layout. I have tried adding it to various places without the desired result.
Attached is an image of the app after a small amount of scrolling has been performed with the collapsing toolbar above not reducing it's height.
<?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"
tools:context=".ui.ArticleListActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/theme_primary"
app:contentScrim="#color/theme_primary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/empty_detail"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/app_name"
android:src="#drawable/logo" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
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/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
According to your code what's missing is that you have to set the scrolling flag "scroll" to the imageview above the Toolbar.
I've done a similar thing and as you can see on the code below, all the views that are meant to react to the RecyclerView Scrolling have the scrolling flag and they are before the views that we don't want to scroll such asthe Toolbar:
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:id="#+id/collapsingToolbar"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
>
<include layout="#layout/movie_details_header_layout" android:id="#+id/headerLayout"
app:layout_scrollFlags="scroll"
/>
<android.support.v7.widget.Toolbar
android:layout_height="56dp"
android:layout_width="match_parent"
android:id="#+id/toolbar"
app:navigationIcon="#drawable/ic_arrow_back"
android:navigationContentDescription="Back"
app:layout_collapseParallaxMultiplier="0.7"
app:layout_collapseMode="pin"
/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
The project came using version 22.x of the compat libraries, updating to 23 seemed to fix everything.
I am using Support Design Library rev. 23.0.1 (and 22.2.1 as well). The problem is after activity orientation changes if RecyclerView (placed in fragment) has been scrolled, it loses its top padding which is probably equal to StatusBar Height + AppBar Height (as you see on a picture).
See this sample video for details
Here is my Activity layout
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/discount_activity_app_bar_layout"
android:layout_width="match_parent"
android:layout_height="256dp"
app:layout_behavior="com.moskart.mosfake.widget.AppBarLayoutBehavior"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true"
>
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="#dimen/expanded_toolbar_title_margin_start"
app:expandedTitleMarginBottom="96dp"
app:expandedTitleTextAppearance="#style/TextAppearance.Design.CollapsingToolbar.Expanded"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/hero_image"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7"
android:fitsSystemWindows="true"
/>
<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"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:behavior_overlapTop="64dp"
android:fitsSystemWindows="true" >
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment"
android:name="com.moskart.mosfake.fragment.DiscountFeedFragment"
tools:layout="#layout/fragment_discount_feed"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
And a simple fragment contains RecyclerView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.moskart.mosfake.fragment.DiscountFeedFragment"
>
<com.moskart.mosfake.widget.GridRecyclerView
android:id="#+id/recycler_view_discount_feed"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
By the way, I found some following issues, but these answers doesn't solve my problem. I've also tried approaches described here and here, but it has no effect, or I doing something wrong.
Thanks for your help!
I have the following layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="br.com.myproject.view.fragment.ProductActivityFragment"
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/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_scrollFlags="scroll|exitUntilCollapsed"
tools:contentScrim="?attr/colorPrimary"
tools:expandedTitleMarginStart="48dp"
tools:expandedTitleMarginEnd="64dp"
android:fitsSystemWindows="true">
<ImageView
android:id="#+id/ivImgProduct"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
tools:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
tools:layout_scrollFlags="scroll|enterAlways"
tools:popupTheme="#style/ThemeOverlay.AppCompat.Light"
tools:layout_collapseMode="pin">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/rvProductActions"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior">
</android.support.v7.widget.RecyclerView>
</android.support.design.widget.CoordinatorLayout>
The RecyclerView is getting on the Toolbar are staying with an appearance "overlapped". The scroll both RecyclerView as the CollapsingToolbarLayout not working.
I'm trying to leave my layout with the behavior as this example link, but using RecyclerView.
After many attempts I used a library called Android-ObservableScrollView and it worked. It is simpler to use, provides several examples and a single component already has the desired effect. Scroll content has to be greater than the empty screen space for the scroll to take effect because it does not have the bounce effect of iOS.
You have to add app:layout_behavior="#string/appbar_scrolling_view_behavior" to your recyclerview
The behavior of CollapsibleToolbarLayout with regards to the RecyclerView seems broken. When setting a value for
app:layout_scrollFlags
If you do not use "scroll|enterAlways", the Collabsible layout will never expand. It will always contract, but when you pull down, it does not expand anymore, so it just gets locked to the top.
If you use "scroll|enterAlways", it works as expected, meaning it instantly expands the header to its full height whenever you scroll down.
Without knowing anymore, it seems as if the Collapsible layout cannot properly determine when the RecyclerView is at the top of the list, as that is the criteria for when it should expand to full height in the other cases.
Here is the layout that I am testing with. The java code isn't really important, it is just populating the recyclerview with dummy data and using a LinearLayoutManager.
<?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"
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="200dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:toolbarId="#id/toolbar_id"
app:contentScrim="#color/white"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_id"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
Try with scroll|enterAlways|enterAlwaysCollapsed. This way the toolbar should always enter in the collapsed mode, and then expand when you reach the top of the sibling view.
If you want to show a list with RecyclerView under the AppBarLayout you should place the RecyclerView XML under
<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:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="200dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:toolbarId="#id/toolbar_id"
app:contentScrim="#color/white"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_id"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<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.CoordinatorLayout>