46
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-04-17

実現したいレイアウト

スクリーンショット 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>
46
20
1

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
  3. You can use dark theme
What you can do with signing up
46
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?