Jetpack Compose入門(8) コンポーネントを装飾する

前回、Text()コンポーネントを使った文字列の表示方法を確認し、文字色や文字サイズなどいくつかのパラメータを変更しましたが、もう少し見た目を変更したいときにはどうすればよいでしょうか。例えば背景色を変えたい、枠線を表示したい、文字列の周りに余白を持たせたい、などの要望が出てくると思います。そういうときのために、今回はModifierの使い方を確認していきます。

modifier引数

“Modifier”とは聞きなれない単語ですが、直訳すると「修飾子」です。Jetpack Composeにおいては、UIコンポーネントの見た目や機能をコントロールする役割を担っています。前回確認したText()の定義をもう一度見てみましょう。

@Composable
fun Text(
    text: String,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontStyle: FontStyle? = null,
    fontWeight: FontWeight? = null,
    fontFamily: FontFamily? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    textDecoration: TextDecoration? = null,
    textAlign: TextAlign? = null,
    lineHeight: TextUnit = TextUnit.Unspecified,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    onTextLayout: (TextLayoutResult) -> Unit = {},
    style: TextStyle = LocalTextStyle.current
): @Composable Unit

2つ目の引数にmodifierという引数があります。この引数に、Modifierオブジェクトを設定することによって、Textコンポーネントの見た目や機能をカスタマイズすることができます。Jetpack Composeで提供されている多くのコンポーザブル関数には、同じようにmodifier引数が用意されているので、適切に設定することでUIのカスタマイズができるのです。

Modifierオブジェクト

modifier引数には、Modifierオブジェクトを渡します。”Modifier“で空っぽのModifierオブジェクトを取得し、これにメソッドチェーンで必要な装飾を書き連ねていきます。例えば、背景を灰色にして、幅1dpの赤色の枠をつけて、5dpのパディングをつけるには次のように書きます。

Text(
    text = "Hello",
    modifier = Modifier
        .background(Color.Gray)
        .border(1.dp, Color.Red)
        .padding(5.dp)
)

ところでこの書き方、Modifierクラスのコンストラクタを呼び出していないのになぜオブジェクトが作成されるのかと、不思議に感じませんか? これは、”Modifier“はModifierインターフェースを実装したコンパニオンオブジェクトだからです。Kotlinではインターフェースを実装したコンパニオンオブジェクトは静的オブジェクトではなく呼び出すたびに個別のオブジェクトが作成されます。そのため、コンストラクタを呼び出さずともModifierオブジェクトを取得できるというわけです。まあ、難しく考えずとも、”Modifier“に続けて必要な関数を書き連ねればよいと考えて問題ないでしょう。

それでは、いくつか実際に試してみましょう。

Modifierの例

まずは背景に色を付けてみましょう。

Text(
    text = "Hello",
    modifier = Modifier.background(color = Color(0xff66cdaa))
)

少々窮屈な感じなので、パディングを追加します。

Text(
    text = "Hello",
    modifier = Modifier
        .background(color = Color(0xff66cdaa))
        .padding(20.dp)
)

背景は形を指定することもできます。

Text(
    text = "Hello",
    modifier = Modifier
        .background(Color(0xff66cdaa), RoundedCornerShape(20.dp))
        .padding(20.dp)
)

枠線も追加しましょう。太さ、色、形を指定します。

Text(
    text = "Hello",
    modifier = Modifier
        .background(Color(0xff66cdaa), RoundedCornerShape(20.dp))
        .border(2.dp, Color(0xff2f4f4f), RoundedCornerShape(20.dp))
        .padding(20.dp)
)

ここで注意すべきはborder()padding()の順番です。padding()を先に呼び出すと、パディングを確保した後の描画エリアに対して枠線を描画するので、期待した通りにはなりません。

Text(
    text = "Hello",
    modifier = Modifier
        .background(Color(0xff66cdaa), RoundedCornerShape(20.dp))
        .padding(20.dp)
        .border(2.dp, Color(0xff2f4f4f), RoundedCornerShape(20.dp))
)

サイズと位置も調整できます。

Text(
    text = "Hello",
    modifier = Modifier
        .size(120.dp, 80.dp)
        .offset(20.dp, 20.dp)
        .background(Color(0xff66cdaa), RoundedCornerShape(20.dp))
        .border(2.dp, Color(0xff2f4f4f), RoundedCornerShape(20.dp))
        .padding(20.dp)
)

リファレンス

Modifierの主な関数は、androidx.compose.uiパッケージに定義されていますが、それ以外にも特定のレイアウトコンポーネントの中だけで使える拡張関数がいろいろ定義されています。「Compose 修飾子のリスト」にはそれらが横断的にまとめてあるので、目的にあったModifierの関数を探すのに便利です。

まとめ(と補足)

今回は、modifier引数を指定してUIコンポーネントの見た目を変更する方法を確認しました。これ以外にもいろいろな装飾を追加することができるので、上で紹介したリファレンスを調べて試してみてください。また今回は、特定のレイアウトコンポーネントのスコープ内だけで使える関数は紹介しませんでしたが、例えば、文字列の配置(センタリングや右寄せなど)を指定するalign()など、よく使うものもあります。このあたりは、レイアウトについて説明するときにまとめて説明します。