I want to create Button which will move together with BottomSheet. It should be positioned above BottomSheet parent. So I used CoordinatorLayout to achieve this. But if I anchor this Button above BottomSheet layout, its bottom half is cut off (I want to position it above BottomSheet layout like in RelativeLayout). Also if BottomSheet is hidden, its overlapping TabBar. Also Button is for some reason not following BottomSheet. I thought CoordinatorLayout would solve this issue. I dont wanna hand animate Button movement based on BottomSheet peek.
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical"
tools:ignore="UselessParent">
<ImageButton
android:id="#+id/but_location"
android:layout_width="#dimen/button_height"
android:layout_height="#dimen/button_height"
android:layout_margin="#dimen/padding_medium"
app:layout_anchor="#id/bottomSheetContainer"
app:layout_anchorGravity="end|top"
android:src="#drawable/ic_location_icon"
style="#style/button.shadow" />
<RelativeLayout
android:id="#+id/bottomLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/bottomSheetContainer"
layout="#layout/bottom_sheet_container"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_above="#id/tabBar" />
<include
android:id="#+id/tabBar"
layout="#layout/tab_bar_layout"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="66dp" />
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
UI:
Related
I have an issue in my APP, I have a BottomSheet and I was adding a FAB, the FAB should be always at the top of the BottomSheet so I have added a bottom margin to the FAB, the issue is that once the BottomSheet is expanded the FAB goes anchored to bottomsheet without the initial bottom margin.
How could I achieve the FAB to be always at the top?
Here is my code:
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="2dp"
android:padding="2dp"
android:scrollbars="vertical"
tools:listitem="#layout/recyclerview_pterm" />
<include
layout="#layout/bottom_sheet_pterm" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="76dp"
android:clickable="true"
android:focusable="true"
app:layout_anchor="#+id/bottomSheet"
app:layout_anchorGravity="top|end"
app:srcCompat="#drawable/ic_covid"
android:contentDescription="#string/verifica_gp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
And here is how it looks like:
You can solve that by adding these two attributes to the FAB:
<com.google.android.material.floatingactionbutton.FloatingActionButton
....
app:useCompatPadding="true"
android:layout_gravity="top" />
The android:layout_gravity="top" makes the FAB to be on top of the anchor (i.e. not intersected with it), and app:useCompatPadding="true" Allows the padding between the FAB & The anchor (i.e. bottomSheet).
Sample:
I made a simple layout in which there is a AppBarLayout (that doesn't scroll), some content in the middle, and a BottomSheet. This BottomSheet is actually a LinearLayout with a BottomSheetBehavior and inside has a RecyclerView.
This BottomSheet when expanded places the RecyclerView on top of the AppBarLayout. The problem is that, when the user tries to scroll this RecyclerView, the AppBarLayout below steals the scroll.
I'm leaving the layout code, but I uploaded the whole example project to GitHub with a GIF to illustrate.
Layout
<?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:id="#+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:liftOnScroll="false">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="#string/app_name" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?colorSurface"
android:gravity="center_vertical"
android:padding="16dp"
android:text="Subtitle"
android:textAppearance="?textAppearanceSubtitle1" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?colorSurface"
android:gravity="center_vertical"
android:padding="16dp"
android:text="Subsubtitle"
android:textAppearance="?textAppearanceBody2" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="56dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="#string/lorem_ipsum"
android:textAppearance="?textAppearanceBody1" />
</androidx.core.widget.NestedScrollView>
<LinearLayout
android:id="#+id/bottom_sheet_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:background="#FFF"
android:elevation="5dp"
android:orientation="vertical"
app:behavior_hideable="false"
app:behavior_peekHeight="64dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/bottom_sheet_header"
android:layout_width="match_parent"
android:layout_height="64dp"
android:gravity="center_vertical"
android:padding="16dp"
android:text="Fruits"
android:textAppearance="?textAppearanceHeadline6" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
I've tried:
Placing the nestedScrollingEnabled attribute in various places, but didn't work and this behavior occurs in old APIs (like JellyBean);
In the original project where I saw this I wrote a custom AppBarLayout behavior to ignore if the target View is the RecyclerView of the BottomSheet, but also didn't work;
Set the whole AppBarLayout GONE when the BottomSheet is expanded and funny enough the AppBarLayout behaves like I set to INVISIBLE (if programmatically set to GONE, it behaves like invisible, if set before inflating, it behaves as expected).
I'm avoiding use a Fragment to create this BottomSheet due to project specifications.
The workaround I did was split the CoordinatorLayout in 2, where one contains the AppBarLayout and the NestedScrollView, and the other one contains the BottomSheet (LinearLayout).
The hierarchy, using the layout of the question as example, end up like this:
<FrameLayout>
<CoordinatorLayout>
<AppBarLayout>
<MaterialToolbar/>
<AppCompatTextView/>
<AppCompatTextView/>
</AppBarLayout>
<NestedScrollView>
<AppCompatTextView/>
</NestedScrollView>
</CoordinatorLayout>
<CoordinatorLayout>
<LinearLayout>
<AppCompatTextView/>
<RecyclerView/>
</LinearLayout>
</CoordinatorLayout>
</FrameLayout>
In my case this works because my BottomSheet doesn't need to coordinate any behavior with the other views.
When having a CollapsingToolbarLayout inside CoordinatorLayout you need to use app:layout_behavior="#string/appbar_scrolling_view_behavior" so the view below the toolbar moves down the height of the toolbar, but in that case this view below the toolbar goes beyond the window itself on the bottom, thus if I want to center something in it between the toolbar and the bottom of the screen it's not really possible?
Here is my code:
<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:orientation="vertical">
<include layout="#layout/generic_toolbar_collapsing" />
<LinearLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<TextView
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/list_view_empty_string"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
And here a screenshot from the layout editor:
The selected view on the picture is the LinearLayout, you can see how the dots go beyond the bottom window line, so the text is centered inside the view, but not centered relative to the toolbar and the bottom of the window, is it possible to achieve this?
I have a persistent bottom sheet inside coordinate layout. I have set bottomsheethideable = true and implemented BottomSheetBehaviour callbacks. Currently, bottom sheet opens in the collapsed mode and when I am scrolling recylerview inside view pager of bottomsheet . BottomSheet also scrolled up that is the default behavior of bottomsheet. I want to keep bottom sheet in collapsed stated utill i reached at last position of recylerview and after then bottomsheet should scroll up and required opposite behavior too.
Inside bottom sheet, there is a view pager. Here is XML file code :
<?xml version="1.0" encoding="utf-8"?>
<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:background="#android:color/transparent"
android:orientation="vertical">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/ll_bottom"
android:background="#android:color/transparent">
<RelativeLayout
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:transitionName="app_bar_layout">
<com.appstreet.pixylz.view.ASToolbar
android:id="#+id/tb_top"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentTop="true"
android:minHeight="?attr/actionBarSize"
app:theme="#style/AppTheme.ActionBarTheme" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignWithParentIfMissing="true"
android:layout_below="#id/app_bar_layout" />
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
<LinearLayout
android:id="#+id/ll_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<include
android:id="#+id/bottom_bar"
layout="#layout/layout_browser_bottom"
android:layout_width="match_parent"
android:layout_height="#dimen/bar_ht_with_9path_shadow"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:background="#color/colorPrimary"
app:tabGravity="fill"
app:tabIndicatorColor="#color/colorAccent"
app:tabIndicatorHeight="3dp"
app:tabMode="fixed" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Someone suggested to create custom BottomSheetBehaviour and disable TouchEvents using return false onTouchEvent and onInterceptTouchEvent inside CustomBottomSheetBehaviour. Using this RecylerView Scrolled and BottomSheet also stayed on collapsed position but on end of recylerview scroll. BottomSheet doesn't dragged Up or Down even sliding outside of recylerview bottomsheet is not dragging.
Anyone can help or suggest solution? Thanks.
I'm having an issue with getting a Bottom Sheet to work properly
In the bottom sheet I have an item above a RecyclerView (a TextView in this case) - both of which I wish to scroll, so they're both wrapped in a NestedScrollView.
Issue is, when the screen loads, the TextView is hidden, and I must scroll the RecyclerView downward to reveal it, before being able to scroll the whole view up again to have the bottom sheet overlay the rest of the screen.
How can I make it so that the TextView is already in view?
```
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:behavior_hideable="false"
app:behavior_peekHeight="auto"
app:layout_behavior="#string/bottom_sheet_behavior">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/colorPrimaryDark"
android:gravity="center"
android:text="GYUHGHJG"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</FrameLayout>
```
how it starts
how it looks after scrolling it down (how it SHOULD start)
I have tried a workaround and it worked!!!
It is not a valid solution but no other option..
In your example, try to use Relative layout instead of Linear layout. and provide top padding to Recycler view.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/colorPrimaryDark"
android:gravity="center"
android:text="GYUHGHJG"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="25dp"/>
</RelativeLayout>