androidxmlkotlinbottom-sheetbottomsheetdialogfragment

BottomSheetDialogFragment won't fill desired height and always wraps content


I am implementing a BottomSheetDialogFragment that I would like to fill half the screen initially with the ability to drag it up to full screen or drag it down to dismiss. So that I could simplify the implementation to find the source of my problem, I created a simple layout file that just has a red background and a text view. The problem I am having is that even when I set the behavior.state to STATE_HALF_EXPANDED, the top of the bottom sheet dialog is at the halfway point of my screen, but the background wraps to fit my text view rather than expanding to fill everything below it. I can still drag it up to full screen but again, the background wraps to my text view rather than filling the available space below. Similarly, if I remove the textView then nothing is shown except the black opaque backdrop that goes behind the BottomSheetDialogFragment

Here is my layout file I am using for my BottomSheetDialogFragment (text.xml):

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ff0000">

    <TextView
        android:id="@+id/textView20"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.5" />

</androidx.constraintlayout.widget.ConstraintLayout>

Here is my implementation of the BottomSheetDialogFragment:

class TestBottomSheet: BottomSheetDialogFragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.test, container, false)
    }

    override fun onViewCreated(
        view: View,
        savedInstanceState: Bundle?
    ) {
        super.onViewCreated(view, savedInstanceState)

        val behavior = BottomSheetBehavior.from(requireView().parent as View)
        behavior.peekHeight = resources.displayMetrics.heightPixels / 2
        behavior.isHideable = true
        behavior.isDraggable = true
        behavior.state = BottomSheetBehavior.STATE_HALF_EXPANDED
    }
}

And here is my function in my activity that shows the BottomSheetDialogFragment.

private val onButtonClick = View.OnClickListener {
    val bottomSheetFragment = TestBottomSheet()

    bottomSheetFragment.show(supportFragmentManager, "BottomSheetDialog")
}

Here are screenshots of what I'm seeing:
When "behavior.state = BottomSheetBehavior.STATE_HALF_EXPANDED"
enter image description here

When "behavior.state = BottomSheetBehavior.STATE_EXPANDED"

enter image description here

I have also tried wrapping my test.xml in a CoordinatorLayout as well with the same result.

What I would like to happen is for the red background to fill up half the screen with the text view centered since the end result of this BottomSheetDialogFragment will have variable content that may take up more or less than half the screen size but the BottomSheetDialogFragment should always take up half the screen with the ability to drag it up to full screen if desired.


Solution

  • Check by replacing your below method as provided code snippet. I have attached snapshot for how it will look.

      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        view.post {
            val parent = view.parent as View
            val params = parent.layoutParams
            val behavior = (params as ViewGroup.LayoutParams).apply {
                height = (resources.displayMetrics.heightPixels * 0.5).toInt()
            }
            parent.layoutParams = behavior
        }
    }
    

    ![snapshot][2]