search
LoginSignup
16

More than 1 year has passed since last update.

posted at

updated at

[Android] ConstraintLayoutでwrap_contentしつつ領域からはみ出さないようにする

実現したいレイアウト

スクリーンショット 2019-04-16 20.54.27.png

特に何の変哲もないレイアウトだが、これをConstraintLayoutで作るのに手こずった話。

素直なConstraintLayout実装

とりあえず上記のレイアウトを素直に作ると以下のようになる。

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="70dp"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#FFDDDD">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:text="販売価格"
        android:textSize="25dp"
        />

    <TextView
        android:id="@+id/price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/title"
        android:layout_marginLeft="10dp"
        android:lines="1"
        app:autoSizeTextType="uniform"
        android:text="2,800"
        android:textSize="40dp"
        />

    <TextView
        android:id="@+id/yen"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/price"
        app:layout_constraintBaseline_toBaselineOf="@+id/price"
        android:gravity="bottom"
        android:text="円"
        android:textSize="20dp"
        />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:text="購入する"
        android:textSize="25dp"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

問題点

しかし、このレイアウトには問題があり、価格が大きくなるとボタンと価格が重なってしまう。
※分かりやすくするためボタンは半透明化
スクリーンショット 2019-04-16 21.01.00.png

解決方法

  1. 値段layout_constrainedWidthtrue にする
  2. の右端を購入するの左端につける
  3. 値段の右端をの左端に付ける
    <TextView
        android:id="@+id/price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/title"
        app:layout_constraintRight_toLeftOf="@+id/yen"
        android:layout_marginLeft="10dp"
        android:lines="1"
        app:autoSizeTextType="uniform"
        android:text="2,811"
        app:layout_constrainedWidth="true"
        android:textSize="40dp"
        />

    <TextView
        android:id="@+id/yen"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/price"
        app:layout_constraintRight_toLeftOf="@+id/button"
        app:layout_constraintBaseline_toBaselineOf="@+id/price"
        android:gravity="bottom"
        android:text="円"
        android:textSize="20dp"
        />

layout_constrainedWidthtrue にすることで wrap_contentの中身が大きくても、Constraintをはみ出さないよう幅を制限できる。
また、layout_constrainedWidthを有効にするために、左右両端にConstraintをつける必要がある。

スクリーンショット 2019-04-17 17.51.06.png

これで価格がはみ出ることはなくなった。

位置調整

しかし、上の方法ではまだ問題があり、価格が短い場合は価格と円が左寄せにならなくなってしまう。

スクリーンショット 2019-04-17 17.52.18.png

これを調整するために以下の対応が必要になる。

  1. layout_constraintHorizontal_chainStyle="packed" を指定して価格と円をくっつける
  2. layout_constraintHorizontal_bias="0" を指定して左端によせる

layout_constraintHorizontal_chainStyle は双方向にConstraintで結ばれたView同士をくっつけるか、分散させるかを指定することができる。
これをpackedにすることで価格と円がくっつくが、標準では中央寄せになってしまうので、位置を左寄せにするため layout_constraintHorizontal_bias を0に設定する。

以下が最終的なレイアウトファイル。

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="70dp"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#FFDDDD">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:text="販売価格"
        android:textSize="25dp"
        />

    <TextView
        android:id="@+id/price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/title"
        app:layout_constraintRight_toLeftOf="@+id/yen"
        android:layout_marginLeft="10dp"
        android:lines="1"
        app:autoSizeTextType="uniform"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="0"
        android:text="300"
        app:layout_constrainedWidth="true"
        android:textSize="40dp"
        />

    <TextView
        android:id="@+id/yen"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/price"
        app:layout_constraintRight_toLeftOf="@+id/button"
        app:layout_constraintBaseline_toBaselineOf="@+id/price"
        android:gravity="bottom"
        android:text="円"
        android:textSize="20dp"
        />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:text="購入する"
        android:textSize="25dp"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
16