📊

Jetpack Compose のレイアウトまとめ2: alignment, weight, arrangement

2022/10/16に公開

前回は Jetpack Compose でのレイアウトの基本的な仕組みの部分を解説しました。

https://zenn.dev/wm3/articles/f7393d910fa312

今回は BoxColumnRow での位置揃えや余白を埋める方法を解説します。同じ事をするのにいくつか方法があるので、一通り知っておくとより便利な選択肢が選べたりするでしょう。

代表的な配置方法

今回説明する配置方法は以下の通りです。コンポーネント引数で一括指定する方法と、modifier 等で個別指定する方法があります。

機能 一括指定 個別指定
aligment
位置を揃える
Box(contentAlignment = …)
Column(horizontalAlignment = …)
Row(verticalAlignment = …)
Modifier.align(…)
weight
要素を広げて余白を埋める
- Modifier.fillMaxSize(…)
Modifier.weight(…)
arrangement
要素間の余白を分配する
Column(verticalArrangement = …)
Row(horizontalArrangement = …)
Modifier.padding(…)
Spacer(…)

位置揃え

Box の位置揃え

Box の位置揃えの方法は contentAlignment 引数を使う方法と Modifier.align() を使う方法があります。また Box を使う代わりに Modifier.wrapContentSize() を使う事で同等の表示が可能です。

// Box への引数で設定
Box(contentAlignment = Alignment.Center) { Text("🍄") }

// Box の子要素への Modifier.align() で設定
Box { Text("🍄", Modifier.align(Alignment.Center)) }

// Modifier.wrapContentSize() で設定
Text("🍄", Modifier.wrapContentSize(Alignment.Center))

上のように Alignment.Center を使う事でセンタリングを行う事ができます。Alignment の値は以下の通りです。

左(LTRの場合) 中央 右(LTRの場合)

Alignment.TopStart

Alignment.TopCenter

Alignment.TopEnd

Alignment.CenterStart

Alignment.Center

Alignment.CenterEnd

Alignment.BottomStart

Alignment.BottomCenter

Alignment.BottomEnd

Column / Row の位置揃え

Column / Row の位置揃えの方法は horizontalAlignment / verticalAlignment 引数を使う方法と Modifier.align() を使う方法があります。位置揃えは Column なら水平方向、Row なら鉛直方向です。 Column で鉛直方向、あるいは Row で水平方向で揃える場合は arrangement を使います(後述します)。

// 一括設定
Column(horizontalAlignment = Alignment.CenterHorizontally) {
    Text("Android")
    Text("❤️")
    Text("Jetpack Compose")
}

// 個別設定
Column {
    Text("Android")
    Text("❤️", Modifier.align(Alignment.CenterHorizontally))
    Text("Jetpack Compose")
}
一括設定
Column(horizontalAlignment = …)
Row(verticalAlignment = …)
個別設定
Modifier.align(…)
Alignment.Start
左(デフォルト)
Alignment.CenterHorizontally
中央(水平方向)
Alignment.End
Alignment.Top
上(デフォルト)
Alignment.CenterVertically
中央(鉛直方向)
Alignment.Bottom

weight を使って余白を埋める

Column / Row の子要素を広げて余白を埋めるには Modifier.weight() を使います。

Row {Box(Modifier.weight(1f))}

weight を設定した結果

一つの Column / Rowweight() を持つ要素が複数ある場合は、それぞれに渡された数値の大きさに合わせて分配されます。weight() を持つ要素が一つしかない場合は(0 より大きければ)値に関係なくなるべく広く表示されます[1]

Column / Row の余白の分配

Column / Row で出来た余白を分配するには verticalArrangement / horizontalArrangement 引数を使います(Alignment ではなく Arrangement である事に注意しましょう)。

Column(verticalArrangement = Arrangement.spacedBy(24.dp)) {}

arrangemnt を設定した結果

個別で余白を設定する

固定長であれば Modifier.padding() を使う事で余白を作る事ができます。また、余白を作るための Spacer というコンポーネントもあります[2]Spacerweight() を指定する事で、可変長の余白をセットする事ができます。

Row(Modifier.fillMaxWidth()) {
    Box(Modifier.size(40.dp).border(1.dp, Color.Red))
    Spacer(Modifier.weight(1f))
    Box(Modifier.size(40.dp).border(1.dp, Color.Red))
}

余白の個別設定の結果

まとめ

今回は Jetpack Compose の alignment, weight, arrangement を解説しました。前回の仕組みの部分と合わせた内容で、通常のレイアウトあれば問題なくレイアウトができる事が多いと思います。

次回

https://zenn.dev/wm3/articles/046d6df42b0f9a

脚注
  1. 一見 Modifier.fillMaxSize() と同じような動きに見えます。しかし Modifier.fillMaxSize() は後続の要素のサイズを適切に考慮してくれません。Column / Row に対して縦方向 / 横方向を広げる場合は常に weight() を使うのが無難です。 ↩︎

  2. 非常に細かい事ですが、Spacer の代わりに Box を使ってはいけないのかと思う人がいるかもしれません。個人的には別に構わないのではないかと思います。ソースを見る限りでは、SpacerBox の違いほとんど無く、パフォーマンスの違いもほぼ無いように見えます。開発チームで既に Spacer を使っているなら使い続ける事は良いと思いますが、既に Spacer の代わりに Box を使っている中で Spacer に置き換えていく意味があるか? と言われると、通常はないと思われます。 ↩︎

Discussion