I have a very simple layout that I need to render into a BottomSheetDialog
. The layout is just a scrolling view containing just TextView
s and a button below the scrolling view (so the button is fixed at the bottom and always visible.)
This is just a distilled version of what's in my app, but it will suffice to explain the problem:
<?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"
android:layout_height="match_parent"
android:layout_width="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:id="@+id/nestedScrollView"
android:fillViewport="true"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toTopOf="@id/ok_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/fine_print_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:gravity="center_horizontal"
android:text="Fine Print"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/fine_print_copy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:text="This is the fine print. It's very detailed. So many carefully crafted details"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/fine_print_header"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<Button
android:id="@+id/ok_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="16dp"
android:text="OK"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/nestedScrollView"/>
</androidx.constraintlayout.widget.ConstraintLayout>>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Here is how I present the layout in my Fragment
code:
val contentView = requireActivity().layoutInflater.inflate(R.layout.bottom_sheet_dialog, null)
val bottomSheetDialog = BottomSheetDialog(requireContext())
bottomSheetDialog.setContentView(contentView)
bottomSheetDialog.show()
What I am expecting to see is what is in the preview in Android Studio:
What I actually see is this:
If I step in with Layout Inspector, I can see that the NestedScrollView
is really there, but it is rendered with height 0px
. It's as if the constraint layout tooling ignored the whole match_constraint
idea and really rendered things as if I called for 0dp
. If I use match_parent
it will render behind the button; if I use wrap_content
the preview shows it rendering outside the bounds. If I set an actual size (e.g. 80dp
) then it will appear: but this is not a scalable solution – I should be able to use match_constraint
here!
I tried all the relevant combinations of top:bottom constraint relationships between the NestedScrollView
and the Button
, tried with and without android:fillViewPort="true"
, tried with and without app:layout_behavior=“@string/appbar_scrolling_view_behavior”
, tried without using a CoordinatorLayout
as the top layout (using a ConstraintLayout
at the top instead) – none of these have ANY effect whatsoever.
Anyone know how to deal with this?
UPDATE:
I was able to make something work (without having to "concede defeat" and switch to RelativeLayout
.) On the NestedScrollView
I set:
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
and now it renders correctly in both the preview and the device.
I would still like to know why MATCH_CONSTRAINT isn't working in this context.