ConstraintLayoutは複雑なレイアウトを作成する時に役立ちます。制約(constraint)という概念を用いていてフラットに柔軟なレイアウトを構成できます。逆に簡単なレイアウトではむしろコードが多少多増える傾向があります。
API 30
ConstraintLayout
View間の制約のやり方は色々あります。旧来の位置を設定するRelativeLayoutと似ているところもありますが、制約という概念でのレイアウト作成という点が異なります。
また、AutoConnectの機能で簡単に作業ができて、複雑なレイアウトをフラットに作成できます。
- horizontal, vertical constraint
- それぞれ1つは少なくとも必要
- 何もしないと[0,0]となり位置が定まらない
- Constraint
- Parent position
- スクリーンをParentとした制約
- Order position
- 他のView間での制約
- Alignment
- 他のViewとの頭合わせ
- Baseline alignment
- 文字のベースラインを合わせる
- Constrain to a guideline
- ガイドラインを作成して別制約を設定できる
- Constraint bias
- 制約間のバイアスを設定
- Parent position
horizontal, vertical constraint
以下、projectをdefaultで作成したことを想定していますので、ConstraintLayoutになっていることが前提です。
Button:
Horizontal Constraint を1つと Vertical Constraint 1つを設定してみました。
- レイアウトファイルの「Design」タグでLayout Editor画面
- PaletteからButtonをドラッグ&ドラップ
- Buttonを上と左にある◎を撰択して上と左端に持って行く
- Buttonを掴んで任意の位置(124dp, 132dp)に動かす
ビルドして実行した画面の表示
ImageView:
同じようにImageViewを作る場合です。ImageViewに画像を入れてみます。
Viewが1つで画面がPortlaitのみであればこれでもいいのですが、Viewが増えると上下左右の4方向にconstraintを入れないとうまくいかなくなります。
Parent position
スクリーンの上下左右を親としてViewに制約を設定する方法です。
以下は、スクリーンTopに対してconstraintを設定して128dpのマージンと、スクリーン右端(Start)に168dpのマージンを取るとこのようになります。
コードを見るとレイアウトの上部のconstraintがparentの上部と右端に設定されているのがわかります。
1 2 3 4 5 6 7 8 9 |
<ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@mipmap/ic_launcher" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="128dp" app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="168dp" /> |
例えばアイコンのTopはParentとのconstraintがあり、layout_marginTopでマージンが128dpに設定されているとわかります。
Order position
View間の順番を制限するものです。例えば下のButtonはImageViewの下部に制約を設定していて、TextViewはImageViewの左端に制約を入れてます。
コードで見るとImageViewのIDを指定してconstraintをいれmarginで距離を決めているのがわかります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@mipmap/ic_launcher" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="128dp" app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="92dp" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" android:layout_marginTop="112dp" app:layout_constraintTop_toBottomOf="@+id/imageView" app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="84dp" /> <TextView android:id="@+id/textView" android:layout_width="94dp" android:layout_height="72dp" android:text="TextView" app:layout_constraintStart_toEndOf="@+id/imageView" android:layout_marginStart="76dp" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="128dp" /> |
Alignment
ImageViewの左端とButtonの左端を整列させます。またTextViewはAlignmentプラスでマージンを取っています。
コードではOrder positionと同様にconstraintをどこにしているか指定しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<ImageView android:id="@+id/imageView" android:layout_width="253dp" android:layout_height="246dp" app:srcCompat="@mipmap/ic_launcher" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="44dp" app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="88dp" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" app:layout_constraintStart_toStartOf="@+id/imageView" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="208dp" /> <TextView android:id="@+id/textView" android:layout_width="95dp" android:layout_height="72dp" android:text="TextView" app:layout_constraintEnd_toEndOf="@+id/imageView" android:layout_marginEnd="24dp" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="148dp" /> |
Baseline alignment
異なる文字サイズや英小文字などのベースライン合わせです。
以前はTextViewを選択すると下に「ab」という小さいアイコンが出てきてクリックするとテキストの「baseline」が現れ、それを掴んで、合わせたいTextViewのbaselineと接続させていきました。
この「ab」がわかりにくかったのでしょうか、今では右クリックで「Show Baseline」から設定していけます。
コードでは
layout_constraintBaseline_toBaselineOf
を使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<TextView android:id="@+id/textView1" android:layout_width="126dp" android:layout_height="78dp" android:layout_marginStart="52dp" android:layout_marginTop="100dp" android:text="Hello" android:textSize="24sp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/textView2" android:layout_width="152dp" android:layout_height="106dp" android:text="World" android:textSize="32sp" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="40dp" app:layout_constraintBaseline_toBaselineOf="@+id/textView1" tools:layout_editor_absoluteY="97dp" /> |
Constrain to a guideline
水平あるいは垂直のガイドラインを作成してそれにViewを整列させます。メニューからVertical, Horizontalを撰択してガイドラインを作成していきます。
その後、ガイドラインにそれぞれのViewのconstraintを設定します。
コードでは android.support.constraint.Guideline が作られています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@mipmap/ic_launcher" tools:layout_editor_absoluteY="113dp" app:layout_constraintStart_toStartOf="@+id/guideline" android:layout_marginStart="116dp" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="113dp" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" tools:layout_editor_absoluteY="229dp" app:layout_constraintStart_toStartOf="@+id/guideline" android:layout_marginStart="116dp" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="326dp" /> <android.support.constraint.Guideline android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/guideline7" android:orientation="vertical" app:layout_constraintGuide_begin="93dp" /> |
Constraint bias
Verticalあるいは、Horizontalで両サイドにconstraintを入れるとbiasを使って比率を設定することができます。
Adjust the view size
Viewの制約を使って位置を設定しましたが、View自体の大きさの設定は別に行います。
- Wrap Content
- 元のViewから適当な大きさに合わせてくれます
- Match Constraints
- match_parentのようにサイズを最大に拡大します
- 尚、match_parentはConstraintLayoutでは使わずに、代わりにこれを使い、コードでは”0dp”とします。
- Fixed
- 決め打ちのサイズで固定します。
Viewのratio(縦横比)を変更できます。
Match Constraintsを設定すると左上に三角形のマークが現れるので、クリックするとratioの項目から変更することができます。
view margins:
メニューにmarginの設定がされていて、デフォルトでは8dpがViewに影響します。
これは適宜変更できます。
文字列をリソースに設定
基本的にリテラルで文字列を書くのは推奨されていません
リソースstrings.xmlに設定してそれを読み出す方法が推奨されています
確かに直書きでエラーにもならずに実機でも表示されるのですが
思わぬバグになる可能性が秘められています
どうなるかわかりませんというので推奨されていないのですね
例えばTextViewを設定する場合では、TextViewのAttributesのtextの設定文字の右端をクリック
「+」ボタンから「String Value」を選択して新しくリソースをつくります
「文字」がresourceのstrings.xmlにあるmojiに設定されて、textView1のtextに表示されています。
activity_main.xml
1 2 3 4 |
<TextView android:id="@+id/textView1" android:text="@string/moji" ... /> |
strings.xml
1 2 3 4 |
<resources> <string name="app_name">TestApp003</string> <string name="moji">文字</string> </resources> |
References:
Build a Responsive UI with ConstraintLayout| Android Developers
ConstraintLayout| Android Developers