How to manage views in CoordinatorLayout? - android

I have such template layout as a part of main activity in an app:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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.HomeActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
app:layout_scrollFlags="scroll|enterAlways"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</com.google.android.material.appbar.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/mobile_navigation" />
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
In fragment section there is another layout with SwipeRefreshLayout (containing RecyclerView) and FloatingActionButton.
What I get
As you can see on picture first items of recycler view goes under toolbar.
If I add such string to Relative layout of fragment:
app:layout_behavior="#string/appbar_scrolling_view_behavior"
recycler view starts "to see" toolbar and moves down to its height:
Result
BUT, as you can see recycler view saved its height and moved out of screen.
I want: recycler adjusts its height. I want it to be always connected with bottom edge and growing when toolbar is hidden.

Related

Restore scroll position of RecyclerView inside NestedScrollView after fragment transition despite assigning Id to XML element

I have an application with two fragments A and B.
Fragment A contains a list of items. When selecting one of the items, app navigates to fragment B. I used navigation component for this purpose.
Fragment A's layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/background_color">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:background="#color/background_color"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="false"
android:minHeight="62dp">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="false"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:contentInsetEnd="0dp"
app:contentInsetStart="0dp"
app:layout_collapseMode="pin">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="#+id/nested_scroll_view"
android:layout_width="match_parent"
android:animateLayoutChanges="true"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:descendantFocusability="blocksDescendants"
android:nestedScrollingEnabled="false"
tools:listitem="#layout/item_product_with_add_button" />
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
After navigating back from fragment B to A, I would like to have exact same scroll position that I left it with. But the RecyclerView has a scroll position of 0 and displays some items at top of list.
According to XML layout, NestedScrollView has Id. I tried many suggested solutions but none of them solve my issue.

Android snackbar looks to be attached to a nested scrollview

I have a weird problem where the Snackbar is being attached to the scroll view, so when a user scrolls the snackbar moves with the scrolling instead of staying position on the bottom of the screen.
I know it's caused by how I've set up my layout but I don't know a solution to either better setup my layout, or stop this behavior.
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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=".MainActivity">
<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:id="#+id/collapse_toolbar"
style="?attr/collapsingToolbarLayoutMediumStyle"
android:layout_width="match_parent"
android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:title="">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="0dp"
app:layout_collapseMode="pin"
app:title="" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_graph" />
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
As you can see I'm wrapping the FragmentContainerView inside of a NestedScrollView which works and allows the CollapsingToolbarLayout to work as expected, as well as the child fragments content to scroll as I want.
Each child fragment just implements a basic layout a bit like:
<androidx.coordinatorlayout.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">
//... Lots of text views etc etc
</androidx.coordinatorlayout.widget.CoordinatorLayout>
I tried removing the top level NestedScrollView and implementing it at each fragment, but that caused lots of issues with the CollapsingToolbarLayout and the child fragment content overlapping etc.
Is there a more straightforward solution to this?
Thanks for any input

Transparent AppBarLayout Toolbar and placing content behind them

So far I've managed to implement AppBarLayout and Toolbar with scroll flags and AppBar scrolling behavior and it all works great. My final goal is to implement something like this:
Netflix App Example
As you can see AppBar is transparent and the content is behind it. And everything else works perfectly.
From my observations when I put app:layout_behavior="#string/appbar_scrolling_view_behavior" (In my case I used app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior") tag CoordinatorLayout does not let me overlap Views (In this case AppBar should overlap my content).
This is my XML:
<androidx.drawerlayout.widget.DrawerLayout
android:id="#+id/drawerLayout"
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:fitsSystemWindows="true">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<fragment
android:id="#+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="#navigation/root_nav_graph"
app:defaultNavHost="true"
/>
</FrameLayout>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$Behavior"
>
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways|snap"
/>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
The fragment holds layout with NestedScrollView as a Root.
Remove the attribute
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
from the Frame Layout. Also, set the attribute android:background="#android:color/transparent" to your toolbar.

Using persistent bottom sheet in fragment with relative layout parent

I have an activity with a coordinator layout as a parent, the activity is composed of a toolbar and viewpager tablayout. The activity has a fragment with a relative layout parent and nested in this relative layout is a recyclerview and a bottom sheet.
Now the problem is that the bottom sheet does not work well with the relative layout but the toolbar scrolls well on recyclerview scroll event.
However, when I use a coordinator layout as the parent of the fragment layout, the bottom sheet works fine but the tab fails to scroll hence the bottom sheet is not fully shown.
My question: How can I use bootomsheet in a relativelayout parent. Or can I still use Coordinator layout in the fragment and the parent tab still scrolls well?
Here is the code for the fragment with the relative layout as root layout:
<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"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<include layout="#layout/report_question_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
Here is the code for the fragment with coordinator layout as root layout
<androidx.coordinatorlayout.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"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<include layout="#layout/report_question_bottom_sheet"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Here is the code for my activity with tab layout
<androidx.coordinatorlayout.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"
tools:context=".Bookmarks">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:tabGravity="fill"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
I expect the toolbar to scroll out of view when scrolling down the recylerview items and scroll into view when scrolling up the recyclerview items.
You can check the doc:
BottomSheetBehavior is applied to a child of CoordinatorLayout to make that child a persistent bottom sheet.
BottomSheetBehavior works in tandem with CoordinatorLayout to let you display content on a Bottom sheet.

Fragment content is overlaying Toolbar

I recently started messing around with the new components of AppCompat 21 and implementing Material Design. Currently, I have an ActionBarActivity with a Toolbar and am trying to have it host a fragment containing a RecyclerView of TextView items (just to test out Recycler). I have items being displayed, but the text in each view is cut off and the entire Recycler is covering the Toolbar like so:
As you can see, there are three TextViews. Their text is cut off halfway and it's overlaying the Toolbar (no Title I know). The TextView item layouts are contained within a RecyclerView layout, which is the layout of the Fragment. The parent Activity has a FrameLayout -> Toolbar, FrameLayout. I am inserting the Fragment into the Activity's sub FrameLayout. Here's the XML:
Each view in the Recycler:
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textview"
android:layout_width="match_parent"
android:layout_height="48dp"
android:fontFamily="sans-serif"
android:paddingTop="16dp"
android:paddingBottom="20dp"
android:textSize="16sp"/>
The Recycler layout, which is the layout of the Fragment:
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/recycler_tasks"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="stuff.MainActivity$TaskFragment">
</android.support.v7.widget.RecyclerView>
And the parent Activity's layout:
<FrameLayout 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/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:ignore="MergeRootFrame">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
I know it must be something simple but I've been stumped on it for a while, trying various things to no avail.
Please do not forget to add app:layout_behavior="#string/appbar_scrolling_view_behavior" to your content 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:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Use RelativeLayout instead of FrameLayout as top parent. Then just add dependencies like layout_above for the Toolbar or layout_below for the fragment container.

Categories

Resources