ConstraintLayoutでwrap_contentしつつmatch_constraintする方法が分からなくて困っていたのでメモ。
ConstraintLayout 1.1.2 時点での書き方です。
wrap_contentしつつmatch_constraintが必要なパターン
これが必要なのは、画面がDialogFragment※で、ConstraintLayoutの中にScrollViewがあり、その中に巨大なViewがあるパターンです。
通常はScrollViewをmatch_constraintして解決すると思いますが、画面がダイアログの場合にmatch_constraintすると表示されません。
※今回はAppCompatDialogFragmentのonCreateDialogでinflate、setViewしています。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BlankFragment">
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="タイトル"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>
Android StudioのPreviewだと正常ですが、実際動かすとタイトルだけになります。
解決策
ScrollViewにwrap_contentを指定しつつ、layout_constrainedHeight="true"を付けます。
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BlankFragment">
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="タイトル"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ScrollView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n Hello World!\n"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>
期待通りに表示されます。
古い書き方
以前はScrollViewをmatch_constraintしつつ、layout_constraintHeight_defaultでwrapを指定する方法でした。
こちらはdeprecatedになっています。
横方向に適用したい
横方向に適用する場合は、heightをwidthに書き換えてください。
参考
android - Wrap_content view inside a ConstraintLayout stretches outside the screen - Stack Overflow
https://stackoverflow.com/a/40881429