I have a detail activity that show the details of a game in my app. The layout is composed mainly by a CollapsingToolbarLayout with the game cover and a NestedScrollView containing the details. The layout is like this:
And scrolled like this:
The XML files for the layout are:
<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/game_detail_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".activities.GameDetailActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="#dimen/app_bar_height"
android:fitsSystemWindows="true"
android:theme="#style/AppTheme.AppBarOverlay">
<net.opacapp.multilinecollapsingtoolbar.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="#+id/toolbar">
<ImageView
android:id="#+id/toolbar_cover"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/game_cover"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/scrim" />
<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/AppTheme.PopupOverlay" />
</net.opacapp.multilinecollapsingtoolbar.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_game_detail" />
<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"
app:layout_anchor="#id/app_bar"
app:layout_anchorGravity="bottom|end"
app:srcCompat="#drawable/ic_favorite_border_black_24dp" />
</android.support.design.widget.CoordinatorLayout>
And the content_game_detail is:
<android.support.v4.widget.NestedScrollView 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/game_detail_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".activities.GameDetailActivity"
tools:showIn="#layout/activity_game_detail">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- There are 11 TextViews here for all the info -->
<android.support.v7.widget.RecyclerView
android:id="#+id/videos_recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/simple_margin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/videos_lable" />
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>
The problem is: when the summary is very long and there are videos to add items to the RecyclerView, the layout start a little scrolled below the expanded toolbar like this:
I need to scroll the view back down to see the top of the information. Testing, I narrowed down the problem to the RecyclerView. When I remove it, this problem doesn't happen. It seems that when the items are added to the RecyclerView, the layout scroll itself up to compensate, but I couldn't found why this happens (instead of just expand the view down) nor how to solve it. Does anyone have any idea?
Related
My recyclerview's items are loaded dynamically. The bottom sheet UI is a small music player. I want to show the recyclerview above the music player UI. But currently, the music player UI is hiding the last elements of recyclerview. The music player's ui is hidden/shown dynamically. Can you please show me how the recyclerview's elements can all be shown without being obstructed by the bottomsheet UI(music player)?
Here is my layout
<?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/main_content"
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="#dimen/detail_backdrop_height"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="#+id/backdrop"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:fitsSystemWindows="true"
android:scaleType="fitCenter"
android:transitionName="#string/transition_album_cover"
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"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<FrameLayout
android:id="#+id/bottom_ui_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_behavior="#string/bottom_sheet_behavior">
<include layout="#layout/music_player_ui" />
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
Just set paddingBottom and clipToPadding="false" to the recyclerView
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="your_music_player_ui_height" />
Try setting the height of the RecyclerView to "0dip" and if using a ConstraintLayout, constrain the RecyclerView to the top and bottom of the parent view.
You can fix this issue by putting the recycler view inside the frame layout.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
</FrameLayout>
I want AppBarLayout to remain in collapsed state for some of the fragments and remained open for other..Basically, i am looking for a function call which will make appbarlayout collapse/uncollapse programatically.... I have tried almost all methods listed on this stack over flow page, but none is working for me. Can someone please help.
Similar stack over flow page , tried most of things here but notworking..
Need to disable expand on CollapsingToolbarLayout for certain fragments
thanks for your time
Layout file
<?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="app.com.navact.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/appBarLayout"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
android:id="#+id/backdrop"
android:layout_width="match_parent"
android:layout_height="256dp"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<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.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/fragment_container"
android:orientation="vertical"
android:paddingTop="0dip"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</FrameLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
You can call appBarLayout.setExpanded(true) to expand the app bar layout and appBarLayout.setExpanded(false) to collapse it.
To lock the app bar layout into the expanded or collapsed state, call setNestedScrollingEnabled(false) on the scrolling view that moves the app bar. That view will somewhere in the view hierarchy of the fragment in your fragment container.
Im trying to use the coordination layout in my app, Im using collapsing toolbar layout at the top and nested scrol view in the content. I also have an image in the toolbar.
My problem is that in fast scrolling, users will need to scroll twice to go from bottom to the top, one for going to the top of the content, and another to expand the toolbar and image, how can I implement so users can scroll from bottom of the content to top of the navigation in one scroll?
<?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.appchar.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: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:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
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/AppTheme.PopupOverlay"/>
</android.support.design.widget.CollapsingToolbarLayout>
</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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/text_margin"
android:text="#string/large_text"/>
</android.support.v4.widget.NestedScrollView>
<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>
I have a layout like the following:
(Toolbar,
Header View, Text View, RecyclerView)
I need the header to be collapsed when I scrolling recyclerview's items.
So that the view "Choose item" and recyclerview left on the screen.
I saw examples when toolbar is being collapsed, but I need toolbar to be present always.
Which layouts/behavior should I use to get this work?
You can achieve it by having this layout:
<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">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<!-- HEADER -->
<RelativeLayout
...
app:layout_collapseMode="parallax">
.....
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
<!-- IF YOU WANT TO KEEP "Choose Item" always on top of the RecyclerView, put this TextView here
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="choose item" />
-->
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
You pin your toolbar by having the app:layout_collapseMode="pin" property set. You make RecyclerView properly scrollable by setting app:layout_behavior="#string/appbar_scrolling_view_behavior" and that's pretty much it.
NB! Position of "Choose item" TextView depends on the particular behaviour you want to achieve:
you can include it as a first element of your RecyclerView's Adapter to scroll it away, once user start scrolling through the RecyclerView;
you can add it into AppBarLayout so it will always stick on top of the RecyclerView, whenever you scroll it or not;
You can read more here Android Design Support Library and here Design Support Library (III): Coordinator Layout
I hope, it helps!
The below code is working but not smooth scroll compare reqular recyclerview I thought.
<?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/activity_main"
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">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<com.sliderbanner.views.BannerSlider
android:id="#+id/banner_slider1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:animateIndicators="true"
app:defaultIndicators="dash"
app:interval="5000"
app:loopSlides="true"
/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize">
<ImageView
android:id="#+id/image_github"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="right"
android:layout_marginRight="8dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="sans-serif-bold"
android:gravity="center_vertical|left"
android:text="Banner Slider"
android:textColor="#android:color/black"
android:textSize="18sp" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</android.support.v7.widget.RecyclerView>
</android.support.design.widget.CoordinatorLayout>
I have an outer CoordinatorLayout that has, as AppBar, the Toolbar and a TabLayout bar and, as content, a ViewPager with appbar_scrolling_view_behavior:
<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:id="#+id/main_content"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity" >
<android.support.design.widget.AppBarLayout android:id="#+id/appbar"
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:popupTheme="#style/AppTheme.PopupOverlay"
app:layout_scrollFlags="scroll|enterAlways|snap">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout android:id="#+id/tabs"
android:layout_width="match_parent" android:layout_height="wrap_content"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager android:id="#+id/container"
android:layout_width="match_parent" android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton android:id="#+id/fab"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end|bottom" android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
When a tab is selected, the ViewPager is updated with a FrameLayout containing another CoordinatorLayout.
This one should display a collapsable Google Map fragment on top of a RecyclerView (showing a vertical list of items).
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<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:id="#+id/nearby_content"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity" >
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways">
<fragment
android:id="#+id/mapFragment"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="300dp"
app:layout_collapseMode="parallax" />
</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="wrap_content"
app:behavior_overlapTop="184dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
</FrameLayout>
The expected behavior is that when the user touches inside the map, the map itself should receive the gesture and therefore pan the view.
While if the user scrolls upwards starting the gesture from inside the visible part of the list, the list (RecyclerView) should slide over the collapsing Map, until the AppBar is reached. At that point further scrolling up should slide only the list.
The problem arises when the gesture is not too much slow: part of the scrolling (roughly the equivalent of the TabLayout height) is consumed by the RecyclerView before it reaches the AppBar.
Also, after scrolling all the way up the list, scrolling down first expands the map and then slides the list (leaving the first part of the list hidden), when it should do the viceversa.
Before scrolling up
After scrolling all the way up and down a bit
I'm not very sure about the answer but you can try adding android:nestedScrollingEnabled="false" inside your recycler view:
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:behavior_overlapTop="184dp"
android:nestedScrollingEnabled="false"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
Hope it helps.