Jetpack Composeのレイアウト

Jetpack Composeでレイアウトを組むための基本的なまとめです

Kenji Abe
10 min readSep 15, 2020
Photo by La-Rel Easter on Unsplash

Jetpack Composeでは、これまでのViewシステムとは違うためレイアウトを組むのに手こずったので、基本的なことを簡単にまとめました。

ConstraintLayoutについては今回は触れてません。

Composeのバージョンはalpha02を使っています。

レイアウトComposable

レイアウトを組むのに使用できるComposableです。これらを組み合わせてレイアウト組んでいくことになります。

Box

Box(
modifier = Modifier.preferredSize(120.dp, 60.dp),
backgroundColor = Color.Yellow,
gravity = ContentGravity.Center
) {
Text(text = "Sample")
}

サイズを指定して描画するものになります。もしサイズが親より大きいものが指定されたときは、それを超えることはないです。

gravity で中にある要素の配置を指定することができます。
( Modifier.gravity とは異なる)

単純にサイズを指定して描画したいときに使えるかと思います。

Stack

Stack {
Box(
modifier = Modifier.preferredSize(120.dp),
backgroundColor = Color.Yellow
)
Box(
modifier = Modifier.preferredSize(80.dp),
backgroundColor = Color.Blue
)
Box(
modifier = Modifier.preferredSize(40.dp),
backgroundColor = Color.Red
)
}

これは上に要素を重ねていくレイアウトになります。FrameLayout みたない感じですね。

Column

Column {
Box(
modifier = Modifier.preferredSize(120.dp, 30.dp),
backgroundColor = Color.Yellow
)
Box(
modifier = Modifier.preferredSize(120.dp, 30.dp),
backgroundColor = Color.Blue
)
Box(
modifier = Modifier.preferredSize(120.dp, 30.dp),
backgroundColor = Color.Red
)
}

上から下に順番に並べていきます。

もし親の領域を超える要素があった場合も特にスクロールなどはひょうじされず、単純に超えたぶんはみ出すことになります。

Row

Row {
Box(
modifier = Modifier.preferredSize(60.dp, 120.dp),
backgroundColor = Color.Yellow
)
Box(
modifier = Modifier.preferredSize(60.dp, 120.dp),
backgroundColor = Color.Blue
)
Box(
modifier = Modifier.preferredSize(60.dp, 120.dp),
backgroundColor = Color.Red
)
}

Column とは逆にこちらは左から右に並べていきます。

RowColumn と同様に親の領域を超える場合は単純にはみ出します。

ScrollableColumn / ScrollableRow

ScrollableColumn {
(0..20).forEach { i ->
Box(
modifier = Modifier.preferredSize(120.dp, 20.dp),
backgroundColor = colors[i % 3]
)
}
}

スクロール可能な ColumnRow になります。親の領域を超える場合はスクロールではみ出した箇所を表示できるようになります。

LazyColumnFor / LazyRowFor

val colors = listOf(Color.Yellow, Color.Blue, Color.Red)
val items = (0..20).toList()
LazyColumnFor(items) { item ->
Box(
modifier = Modifier.preferredSize(120.dp, 20.dp),
backgroundColor = colors[item % 3]
)
}

ScrollableColumnScrollableRow と見た目上は同じですが、こちらは画面上に表示されてない要素は描画しないため効率が良いです。また使用方法としては引数に描画したいリストを渡すことになります。

サイズが固定で少ないものに関しては、ScrollableColumn でも良いですが、サイズが大きいリストを表示するときはこちらの LazyColumnFor を使うようにしたほうが良いです。

Spacer

Column {
Box(
modifier = Modifier.preferredSize(120.dp, 30.dp),
backgroundColor = Color.Yellow
)
Spacer(modifier = Modifier.preferredHeight(16.dp))

Box(
modifier = Modifier.preferredSize(120.dp, 30.dp),
backgroundColor = Color.Blue
)
}

任意の大きさのスペースをつくることができます。

Size

要素の大きさ Modifier を使って設定していきます。

preferredSize / preferredWidth / preferredHeight

Box(
modifier = Modifier.preferredSize(120.dp),
backgroundColor = Color.Blue
)

preferredSize等では任意の大きさを設定できます。ここに設定したサイズはConstraintLayoutでは上書きされることがあります。

size / width / height

preferred~ と同じく任意の大きさを設定しますが、こちらhConstraintLayoutでは上書きされません。

fillMaxSize / fillMaxWidth / fillMaxHeight

Box(
modifier = Modifier.fillMaxSize(),
backgroundColor = Color.Blue
)

fillMaxSize等では親の領域いっぱいに描画します。

また引数に割合を渡すことができ、デフォルトは1になります。以下の例のように 0.5 を指定した場合は半分の領域に描画することになります。

Box(
modifier = Modifier.fillMaxSize(0.5f),
backgroundColor = Color.Blue
)

Alignment

レイアウトで右寄せ、中央寄せ、下寄せなどが行いたい場合がありますが、Composeは少しクセがあるので、使い方を紹介します。

指定するには Modifier.gravityを使っていきます。

まずは必要になるのが Stack / Column / Rowの子であることです。これらのレイアウトのブロックでは StackScope / ColumnScope / RowScope がレシーバーになります。このScopeが必要となります。

また、このScopeによって設定できる値も異なります。

Stack の場合は縦横の方向で指定が可能です。指定できるのは Alignment になります。この例では、画面の中央にBox を表示することになります。

Stack(modifier = Modifier.fillMaxSize()) {
Box(
modifier = Modifier
.gravity(Alignment.Center)
.preferredSize(60.dp),
backgroundColor = Color.Blue
)
}

Column / Rowそれぞれ横か縦しか指定できません。Column では下寄せのようなことは出来ず、横の位置しか指定できません。
ColumnAlignment.HorizontalRowAlignment.Vertical がそれぞれ指定できます。

この例では右寄せになります。

Column(modifier = Modifier.fillMaxWidth()) {
Box(
modifier = Modifier
.gravity(Alignment.End)
.preferredSize(60.dp),
backgroundColor = Color.Blue
)
}

この例では下寄せになります。

Row(modifier = Modifier.fillMaxSize()) {
Box(
modifier = Modifier
.gravity(Alignment.Bottom)
.preferredSize(60.dp),
backgroundColor = Color.Blue
)
}

基本的なことはこれらを組み合わせればレイアウトを組んでいくことはできると思います。複雑なレイアウトを組むときは、より柔軟な ConstraintLayout やカスタムレイアウトを使っていくことになると思います。

参考

--

--

Kenji Abe
Kenji Abe

Written by Kenji Abe

Programmer / Gamer / Google Developers Expert for Android, Kotlin / @STAR_ZERO

No responses yet