3

I'm using a BottomSheetDialogFragment with a custom layout. I'm trying to have the following setup:

<TextView> -> pinned to the top of the bottom sheet
<RecyclerView> -> wrap_content 
<Button> -> pinned to the bottom of the bottom sheet

Both TextView and Button must be visible at all time (sticky), while the RecyclerView should stay in the middle and scroll without obscuring other views.

This is my layout so far:

<androidx.constraintlayout.widget.ConstraintLayout 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">

    <TextView
        android:id="@+id/title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Title"
        app:layout_constraintBottom_toTopOf="@id/recyclerView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constrainedHeight="true"
        app:layout_constraintBottom_toTopOf="@id/button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/title" />

    <Button
        android:id="@+id/button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

This is what it looks like with a small list of items, where the RecyclerView has no need to scroll.

enter image description here

This is what it looks like with a large list of items. The title stays pinned to the top, but the button doesn't. The button is actually not even visible, even if I scroll down all the way.

enter image description here

What's strange to me is that this same layout works with a regular full screen activity, but it somehow fails with a BottomSheetFragment.

I've already looked at other posts, but none of them helped e.g.

aarnaut
  • 507
  • 6
  • 17
  • Thanks for the help. It turned out to be an issue with the bottom sheet state configuration and not the layout. – aarnaut Nov 09 '21 at 22:38

3 Answers3

1

The height of recycler view shouldn't be wrap_content

If you want recyler in-between your title and footer, the better approach is set height = 0 and pin its top to the bottom title and its bottom to the top of footer (like you already did), it will auto stretch for you

  • 1
    Unfortunately, that doesn't help. The `RecyclerView` gets squashed between the two and it's not visible at all. – aarnaut Nov 04 '21 at 13:02
0

What ended up being the solution is setting the state of bottom sheet to expanded e.g.

val bottomSheetDialog = requireDialog() as BottomSheetDialog
bottomSheetDialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED

I suppose that the bottom sheet never expanded fully, so the layout was never fully visible. I thought that the bottom sheet would expand automatically based on the height of the content, but I was wrong. The layout itself is fine, I didn't have to make any changes to it.

aarnaut
  • 507
  • 6
  • 17
0

To correct this behavior of recyclerview, put below property in your recyclerview layout.

app:layout_constrainedHeight="true"

Also change your parent constraint layout height to wrap content like below :

android:layout_height="wrap_parent"
Hitesh Sarsava
  • 666
  • 4
  • 15