Jetpack Composeのレイアウト
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
とは逆にこちらは左から右に並べていきます。
Row
も Column
と同様に親の領域を超える場合は単純にはみ出します。
ScrollableColumn / ScrollableRow
ScrollableColumn {
(0..20).forEach { i ->
Box(
modifier = Modifier.preferredSize(120.dp, 20.dp),
backgroundColor = colors[i % 3]
)
}
}
スクロール可能な Column
と Row
になります。親の領域を超える場合はスクロールではみ出した箇所を表示できるようになります。
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]
)
}
ScrollableColumn
や ScrollableRow
と見た目上は同じですが、こちらは画面上に表示されてない要素は描画しないため効率が良いです。また使用方法としては引数に描画したいリストを渡すことになります。
サイズが固定で少ないものに関しては、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
では下寄せのようなことは出来ず、横の位置しか指定できません。Column
は Alignment.Horizontal
、Row
は Alignment.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 やカスタムレイアウトを使っていくことになると思います。