'How to make RecyclerView be always up to BottomSheet and under AppBarLayout?
I have a layout with AppBarLayout
which height is set dynamically by adding some margins if the device has the notch, BottomSheetLayout
and a RecyclerView
.
The goal:
I need to make the RecyclerView
fit between the AppBar and the top of BottomSheetLayout
when it's expanded or collapsed, so the items from RecyclerView
never must go under the BottomSheet
or AppBarLayout
.
I was playing with onSlide method to archieve so:
bottomsheet.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
recyclerPiatti.scrollToPosition(listPiatti.size() - 1);
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
findViewById(R.id.arrowIcon).setRotation(slideOffset * 180);
int margin = bottomSheet.getHeight();
if (!Float.isNaN(slideOffset)) {
margin *= (1 - Math.abs(slideOffset));
setRecyclerViewHeight(margin);
}
}
});
And tried to set initial margins of the RecyclerView
in onAttachedToWindow
(where i set dynamically the height of appBar)
bottomsheet.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
recyclerPiatti.scrollToPosition(listPiatti.size() - 1);
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
findViewById(R.id.arrowIcon).setRotation(slideOffset * 180);
int margin = bottomSheet.getHeight();
if (!Float.isNaN(slideOffset)) {
margin *= (1 - Math.abs(slideOffset));
setRecyclerViewHeight(margin);
}
}
});
private void setRecyclerViewHeight(int marginBottom) {
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) recyclerPiatti.getLayoutParams();
params.setMargins(0, findViewById(R.id.appBar).getHeight(), 0, marginBottom);
recyclerPiatti.setLayoutParams(params);
recyclerPiatti.requestLayout();
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Utils.adjustToolbarForNotch(this, findViewById(R.id.appBar));
setRecyclerViewHeight(findViewById(R.id.bottomSheet).getHeight());
}
The layout:
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/menuToolbar"
style="@style/Widget.MaterialComponents.Toolbar.Primary"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/ic_baseline_close_white"
app:title="Menù componibile" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerPiatti"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:listitem="@layout/layout_menu_componibile" />
<LinearLayout
android:id="@+id/bottomSheet"
android:background="@drawable/background_bottomsheet"
android:layout_width="match_parent"
android:layout_height="450dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
app:behavior_hideable="false"
android:elevation="5dp"
app:behavior_peekHeight="200dp"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:gravity="center_horizontal"
android:layout_height="60dp">
<View
android:id="@+id/expandButton"
android:layout_width="75dp"
android:layout_height="40dp"
android:background="@drawable/bottom_border_radius"
android:clickable="true"
android:contentDescription="@string/bottom_sheet_close_button"
android:elevation="8dp"
android:focusable="true"
android:padding="10dp" />
<ImageView
android:id="@+id/arrowIcon"
android:layout_width="75dp"
android:layout_height="40dp"
android:padding="8dp"
android:contentDescription="@string/bottom_sheet_close_button"
android:src="@drawable/ic_keyboard_arrow_up" />
</RelativeLayout>
...
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
But instead it's initial state is not even set and when the BottomSheet is expanded or collapsed the RecyclerView just get resized in a weird way..
The BottomSheet initial state in onCreate is set to EXPANDED.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|