techium

このブログは何かに追われないと頑張れない人たちが週一更新をノルマに技術情報を発信するブログです。もし何か調査して欲しい内容がありましたら、@kobashinG or @muchiki0226 までいただけますと気が向いたら調査するかもしれません。

ConstraintLayoutをXMLでレイアウト定義を行う

AndroidのConstraintLayoutは新しく追加されたレイアウトです。
ConstraintLayoutはLinearLayoutやRelaytiveLayoutでは実現できなかったフラットなビュー階層を使用して、大規模で複雑なレイアウトを作成できるようになりました。
そしてAndroid StudioのLayout Editorでマウス操作で配置や設定を施すことができるようになっています。
便利になりましたが複雑な設定やデバッグなどでXMLで読むことやマウス操作でなくXMLで記述する人はまだまだいます。 そこで今回はConstraintLayoutで使えるタグとその意味を説明いたします。

それぞれの要素の説明はこちらに書かれていますがあまり詳しく書いていないのでそれぞれ実装してみて書き起こしています。 間違っている点などがあればご連絡ください。

親のViewの中央に配置する

次の図のようなボタンを中央に配置してみましょう。

コードは下記のようになります。

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

ここで利用されるConstraintLayoutのタグはそれぞれ次のような定義となります。

タグ 引数 概要
layout_constraintLeft_toLeftOf “parent” or “id” 指定したViewの左端と自身のViewの左端の指定を対応付けます
layout_constraintRight_toRightOf “parent” or “id” 指定したViewの右端と自身のViewの右端の指定を対応付けます
layout_constraintTop_toTopOf “parent” or “id” 指定したViewの上端と自身のViewの上端の指定を対応付けます
layout_constraintBottom_toBottomOf “parent” or “id” 指定したViewの下端と自身のViewの下端の指定を対応付けます

上記の定義ですべてparentを指定すると親ビューに対して全方位の対応付けが行われ、後半に出てくるチェインの指定spreadの影響で中央に表示することができます。

上記のレイアウトを作成すると次のような結果が得られます。

f:id:muchiki0226:20170226050326p:plain:w300

指定したViewの隣に配置する

Viewの隣に配置するには次のタグを利用します。

タグ 引数 概要
app:layout_constraintRight_toLeftOf “parent” or “id” 指定したViewの左側に位置に自身のViewを配置する
app:layout_constraintLeft_toRightOf “parent” or “id” 指定したViewの右側に位置に自身のViewを配置する
app:layout_constraintBottom_toTopOf “parent” or “id” 指定したViewの上側に位置に自身のViewを配置する
app:layout_constraintTop_toBottomOf “parent” or “id” 指定したViewの下側に位置に自身のViewを配置する

実際に上記を利用した時の例は次のようになります。

Viewの左に配置する

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_b"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/button_a"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

f:id:muchiki0226:20170226050332p:plain:w300

Viewの右に配置する

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_b"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/button_a"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

f:id:muchiki0226:20170226050338p:plain:w300

Viewの上に配置する

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_b"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/button_a"/>
</android.support.constraint.ConstraintLayout>

f:id:muchiki0226:20170226050341p:plain:w300

Viewの下に配置する

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_b"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_a"/>
</android.support.constraint.ConstraintLayout>

f:id:muchiki0226:20170226050329p:plain:w300

View間のマージンを設定する

View間のマージンは今までのViewのマージンの指定方法(layout_margin,layout_marginStart,layout_marginTop,layout_marginBottom,layout_marginEnd)で指定できます。

次のようなマージンを設定したとしたとします。

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_b"
        android:layout_marginBottom="50dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/button_a"/>

    <Button
        android:text="Button_C"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_c"
        android:layout_marginTop="16dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_a"/>

    <Button
        android:text="Button_D"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_d"
        android:layout_marginEnd="50dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/button_a"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_E"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_e"
        android:layout_marginStart="16dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/button_a"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

そうすると下図のような表示になります。

f:id:muchiki0226:20170226050344p:plain:w300

ViewがGoneの時のマージンを設定する

ConstraintLayoutは指定したViewがgoneのときとvisibleの時それぞれでマージンのサイズを変更することが可能です。

次のようなレイアウトがあったとします。

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        android:visibility="visible"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_b"
        android:layout_marginStart="16dp"
        app:layout_goneMarginStart="100dp"
        app:layout_constraintLeft_toRightOf="@+id/button_a"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

Button_AがvisibleのためButton_Bはayout_marginStartが適応されるため次のようになります。

f:id:muchiki0226:20170226050413p:plain:w300

そしてButton_Aがgoneになる次のようなレイアウトになったとすします。

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        android:visibility="gone"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_b"
        android:layout_marginStart="16dp"
        app:layout_goneMarginStart="100dp"
        app:layout_constraintLeft_toRightOf="@+id/button_a"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

そうするとlayout_goneMarginStartの値が利用されるようになり次のように表示されるようになります。

f:id:muchiki0226:20170226050407p:plain:w300

layout_goneMarginStartだけでなくlayout_goneMarginEnd,layout_goneMarginTop,layout_goneMarginBottomも定義できます。

バイアスをかけて配置をずらす

ConstraintLayoutは指定したViewの配置は自動的に計算して左右のマージンがデフォルトでは自動的に幅を1:1の比率で配置します。
そこでlayout_constraintHorizontal_bias,layout_constraintVertical_biasを利用すると比率を変更することができます。

次のレイアウトはlayout_constraintHorizontal_biasを0.3に設定した時の例となります。
横方向のマージンを0.3:0.7の比率になり左側に20%ずらした位置になります。

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintHorizontal_bias="0.3"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

上記を利用したら下記のようになります。

f:id:muchiki0226:20170226050350p:plain:w300

次にlayout_constraintVertical_biasを使って縦方向のマージンを0.3:0.7にした例になります。

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintVertical_bias="0.3"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

上記を記載すると次のようになります。

f:id:muchiki0226:20170226050355p:plain:w300

Viewサイズを設定値に応じて動的に変化させる

Viewの横幅や縦幅に設定する場合はwrap_content, match_parentを使われますが他のViewやマージンなどに合わせて最大のサイズに変更するには0dpを指定します。

次の例は横方向のサイズを0dpに指定しマージンを除いた親Viewの最大サイズまで横幅を伸ばす例です。

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

    <Button
        android:text="Button_A"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        android:layout_marginStart="32dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

上記を使うと下図の用になります。

f:id:muchiki0226:20170226054155p:plain:w300

次にConstraintLayoutでは縦の長さに対して横の長さを比率で指定することやその逆の横の長さに対して縦の長さを指定することができるlayout_constraintDimensionRatioというのがあります。

例えば次のようなレイアウトがあったとします。

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:id="@+id/button_a"
        app:layout_constraintDimensionRatio="1:2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

上記を実行すると下図のようになります。 これは0dpで指定したheightかwidthのサイズはlayout_constraintDimensionRatioで指定した値に自動的に計算され表示されます。 layout_constraintDimensionRatioの設定はX:Yという比率で記載します。 ここで注意しなければならないのはX部分は0dpで指定していない方のwidthかheightのサイズが使われます。
上記の例では0dp指定しているのがheightのためwidthの2倍したサイズがheightに自動計算され利用されます。
f:id:muchiki0226:20170226050358p:plain:w300

次のレイアウトではlayout_constraintDimensionRatioにH,Wといった指定を追加した例となります。

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

    <Button
        android:text="Button_A"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:id="@+id/button_a"
        app:layout_constraintDimensionRatio="H,3:1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

上記のレイアウトでは縦横両方に0dp指定しており「H,3:1」と指定しています。 これはHの指定は高さの指定に対してX:Yの長さ指定をするというものです。 Xは縦幅の比率、Yは横幅の比率になります。
先程のH,Wを指定しない時の比率と対応する場所が異なるので注意してください。 上記のレイアウトを利用すると縦幅の1/3倍した横幅が設定される計算になりあmす。
上記を記載すると次のような結果となります。

f:id:muchiki0226:20170226050401p:plain:w300

次はWの時の例です。

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

    <Button
        android:text="Button_A"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:id="@+id/button_a"
        app:layout_constraintDimensionRatio="W,0.5:1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>

上記のレイアウトは「W,0.5:1」となっていますので横幅の半分のサイズの高さが自動的に設定されることになります。
上記のレイアウトを記載すると下記のようになります。

f:id:muchiki0226:20170226050404p:plain:w300

チェインの設定を変更する

チェインはView同士が互いに作用し合うViewのことをチェインと言います。 下記のレイアウトではButton_AとButton_Bが互いに横方向の指定に互いのViewを指定しておりButton_AとButton_Bは同じチェインの設定を利用することになります。
また、チェインは起点となる位置をヘッドと呼び、今回の例ではButton_Aとなります。 チェイン内のViewの配置はチェインの設定に応じて自動的に計算されてマージンが設定されます。 設定するにはlayout_constraintHorizontal_chainStyle, layout_constraintVertical_chainStyleを利用します。 layout_constraintHorizontal_chainStyleは横方向のチェインの設定、layout_constraintVertical_chainStyleは縦方向の設定となります。 チェインのマージンの指定方法の仕方は3種類あります。

Chainの種類 概要
spread デフォルトの設定。View間のすべてのマージンを等間隔になるように設定される
packed 指定したViewをすべて横並びにしくっつけた状態で左右に等倍のマージンを設定する
spread_inside 左右のマージンを0にし内側に配置されるViewは等間隔になるようにマージンが設定される

上記のように設定が可能です。 言葉ではわかりにくいのでそれぞれの例を書いてみました。

下記はspreadを使った例です。

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/button_b"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_b"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/button_a"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>

上記を利用すると下記のようになります。

f:id:muchiki0226:20170226050423p:plain:w300

次にpackedを使った時の例です。

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/button_b"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_b"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/button_a"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>

上記を利用すると下記のようになります。

f:id:muchiki0226:20170226050419p:plain:w300

最後にspread_insideを使った時の例です。

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

    <Button
        android:text="Button_A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/button_b"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_b"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/button_a"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>

実行すると次のようになります。

f:id:muchiki0226:20170226050429p:plain:w300

これらは等倍の配置をする時に利用するチェインの指定でしたがウェイトを使ってチェイン内のViewの幅をコントロールすることも可能です。
それらの指定はlayout_constraintHorizontal_weight,layout_constraintVertical_weightを利用することで可能となります。

下記の例ではButton_AにはWeightを0.2、Button_Bには0.8を指定しておりlayout_widthを0dpにしています。

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

    <Button
        android:text="Button_A"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/button_a"
        app:layout_constraintHorizontal_weight="0.2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/button_b"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <Button
        android:text="Button_B"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintHorizontal_weight="0.8"
        android:id="@+id/button_b"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/button_a"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>

上記を利用するとチェイン内のViewのサイズが次のように2:8の割合でボタンが配置されていることがわかります。

f:id:muchiki0226:20170226050434p:plain:w300

ガイドラインを設定する

レイアウトを作りにあたりアンカーとして何かのViewが置きたくなるケースがあると思います。
そういった時に利用するのがガイドラインタグ「Guideline」を利用します。 縦にガイドラインを作りそのガイドラインに合わせたレイアウトの指定ができるようになっています。

ガイドラインの指定は3種類あります。

タグ 引数 概要
layout_constraintGuide_begin dp 左側を起点に指定したdp分右にずらした位置をガイドラインに設定する
layout_constraintGuide_end dp 右側を起点に指定したdp分左にずらした位置をガイドラインに設定する
layout_constraintGuide_percent float 右側を起点に指定したパーセント分右にずらした位置をガイドラインに設定する

上記の3種類の指定のうち1つだけGuidelineに設定ができ1つのGuidelineに複数の設定を施すことはできないので注意が必要です。

それではそれぞれの例を作りました。

まずはlayout_constraintGuide_beginの例になります。

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

    <android.support.constraint.Guideline
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/guideline"
        app:layout_constraintGuide_begin="100dp"
        android:orientation="vertical"/>

    <Button
        android:text="Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        app:layout_constraintLeft_toLeftOf="@+id/guideline"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

上記を実施すると下図の用になります。

f:id:muchiki0226:20170226050441p:plain:w300

次にlayout_constraintGuide_endの例になります。

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

    <android.support.constraint.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/guideline"
        app:layout_constraintGuide_end="300dp"
        android:orientation="vertical"/>

    <Button
        android:text="Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        app:layout_constraintLeft_toLeftOf="@+id/guideline"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

上記を実施すると次のようになります。

f:id:muchiki0226:20170226050437p:plain:w300

最後にlayout_constraintGuide_percentの例になります。

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

    <android.support.constraint.Guideline
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/guideline"
        app:layout_constraintGuide_percent="0.7"
        android:orientation="vertical"/>

    <Button
        android:text="Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        app:layout_constraintLeft_toLeftOf="@+id/guideline"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

上記を実施すると次の様になります。

f:id:muchiki0226:20170226050445p:plain:w300