"Android dialog constraintlayout"などで調べると山のように出てくるので、ダイアログをいじろうとしたときにみんなぶつかるんだろうなあという感じです。
自分も先人たちと同じ轍を踏んだので、いつかの誰かの助けになれればと思います。
前提
ライブラリ | version |
---|---|
material | 1.6.1 |
constraintlayout | 2.1.4 |
要点
ScrollViewにapp:layout_constraintHeight="wrap_content_constrained"
を指定するとよい。
コード
dialog_scrollable.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="24dp"
android:paddingTop="16dp">
<ScrollView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/checkBox"
app:layout_constraintHeight="wrap_content_constrained"
app:layout_constraintTop_toTopOf="parent">
<!-- スクロールさせたくなる長いコンテンツ -->
</ScrollView>
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="Checked"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
呼び出し側
MainActivity.kt
MaterialAlertDialogBuilder(context)
.setTitle("Title")
.setView(R.layout.dialog_scrollable)
.setPositiveButton("OK", null)
.show()
余談
最初はScrollViewにapp:layout_constraintHeight_default="wrap"
を指定していて、正しく動作していたがログに以下のようなエラーが出力されていた。
E/ConstraintLayout: layout_constraintHeight_default="wrap" is deprecated.
Use layout_height="WRAP_CONTENT" and layout_constrainedHeight="true" instead.
このエラーに従って
dialog.xml
<ScrollView
android:layout_height="wrap_content"
app:layout_constraintHeight="true"
...
と指定すると残念ながらレイアウトが崩れた。どういうことかと悩みに悩み、app:layout_constraintHeight
の定義をcmd+クリックで確認したら
<attr format="dimension|enum|string" name="layout_constraintHeight">
<enum name="match_parent" value="-1"/>
<enum name="wrap_content" value="-2"/>
<enum name="match_constraint" value="-3"/>
<enum name="wrap_content_constrained" value="-4"/>
</attr>
となっていてboolean渡す意味がないということに気づいてしまった。