androidandroid-jetpack-composeandroid-dialogfragmentscaffolding

How to configure the width of a DialogFragment with Compose content?


In my Android application the "about" screen is set up as a dialog as described here:

class AboutDialog : DialogFragment() {

    // ...   

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View = inflater.inflate(R.layout.about_dialog, container, false).apply {
        findViewById<ComposeView>(R.id.about_view).apply {
            setViewCompositionStrategy(DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                AboutScreen()
            }
            isClickable = true
        }
    }

}

... the about_dialog.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.compose.ui.platform.ComposeView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/about_view"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

... the AboutScreen composable:

@Composable
fun AboutScreen {
    MyTheme {
        Scaffold { contentPadding ->
            Box(
                Modifier
                    .padding(contentPadding)
                    .fillMaxSize()
                    .verticalScroll(rememberScrollState())
            ) {
                Column {
                    // ...
                }
            }
        }
    }
}

The dialog (blurry part in the screenshot) expands to some percentage of the screen so that the background screen is visible on the left and right sides.

Screenshot of the dialog screen

How can I configure the width of the dialog?


Solution

  • The following function does the trick for me:

    ... in AboutDialog.kt:

    private fun Window.setPercentageWidth(percentage: Int) {
        val metrics = Resources.getSystem().displayMetrics
        val width = (metrics.widthPixels * (percentage / 100f)).toInt()
        setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT)
    }
    

    ... in the AboutDialog class:

    override fun onStart() {
        super.onStart()
        dialog?.window?.setPercentageWidth(70)
    }
    

    I was worried about flickering due to the order of the Android lifecycle calls ...

    ... but setContent is invoked late for me. No flickering observed.