【Jetpack Compose】Column・Row・Boxでのレイアウト実装方法と違い!
この記事からわかること
- Kotlin/Android Jetpack Composeの使い方
- Column・Row・Boxでのレイアウト実装方法と違い
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Narwhal Feature Drop
- Kotlin:2.1.10
- Material3
- AGP:8.9.2
- Gradle:8.11.1
- Mac M1:Sequoia 15.6.1
Jetpack Compose自体の基本的な使用方法に関しては以下の記事を参考にしてください。
Jetpack Composeにおけるレイアウト実装
Jetpack ComposeではUIコンポーネント(Composable関数)のレイアウト実装を制御するためのComposable関数が用意されています。代表的なものにColumn、Row、Boxという3つのComposable関数があります。公式の解説画像がわかりやすいので引用しておきましたが、それぞれ以下のようなレイアウトでの実装が簡単に行えるようになります。
実際にそれぞれの実装方法をまとめていきたいと思います。
Column
ColumnはUIコンポーネントを縦に並べて配置することができるレイアウトコンテナです。ブロックの中には複数のComposable関数を配置することが可能です。
@Preview(showBackground = true)
@Composable
fun ColumnPreview() {
TestComposeAppTheme {
Column(Modifier.padding(12.dp), horizontalAlignment = Alignment.End) {
ItemText("Hello World!!", Modifier.fillMaxWidth().padding(24.dp))
ItemText("Let's Develop!", Modifier.padding(24.dp))
}
}
}
@Composable
fun ItemText(text: String, modifier: Modifier = Modifier) {
Surface(color = MaterialTheme.colorScheme.primary) {
Text(text, modifier)
}
}
定義
@Composable
inline fun Column(
modifier: Modifier = Modifier,
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
content: @Composable ColumnScope.() -> Unit
)
- modifier・・・任意の修飾
- verticalArrangement・・・縦方向の配置
- horizontalAlignment・・・横方向の配置
- content・・・レイアウト対象のUI
要素間に余白を設ける
要素間に余白を設けたい場合はverticalArrangementにArrangement.spacedBy(XX.dp)を指定します。
Column(
Modifier.padding(12.dp),
horizontalAlignment = Alignment.End,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
ItemText("1", Modifier.fillMaxWidth().padding(24.dp))
ItemText("2", Modifier.fillMaxWidth().padding(24.dp))
ItemText("3", Modifier.fillMaxWidth().padding(24.dp))
ItemText("4", Modifier.fillMaxWidth().padding(24.dp))
}
Row
RowはUIコンポーネントを横に並べて配置することができるレイアウトコンテナです。
@Preview(showBackground = true)
@Composable
fun ColumnPreview() {
TestComposeAppTheme {
Row(Modifier.padding(12.dp), verticalAlignment = Alignment.CenterVertically) {
ItemText("Hello World!!", Modifier.height(150.dp).padding(24.dp))
ItemText("Let's Develop!", Modifier.padding(24.dp))
}
}
}
定義
@Composable
inline fun Row(
modifier: Modifier = Modifier,
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
verticalAlignment: Alignment.Vertical = Alignment.Top,
content: @Composable RowScope.() -> Unit
)
- modifier・・・任意の修飾
- horizontalArrangement・・・横方向の配置
- verticalAlignment・・・縦方向の配置
- content・・・レイアウト対象のUI
UIコンポーネントを比率で配置する
画面の横幅に対してA要素は固定サイズ、B要素は余白分を埋めるように拡大といったViewの配置方法をしたい場合はweightモディファイアを使用します。weightモディファイアは要素が使用するスペースを比率で指定することができ、なので例えば1/3をA要素、2/3をB要素としたい場合は以下のように実装できます。
@Composable
fun BoxTest() {
Row (
modifier = Modifier
.width(300.dp)
.height(150.dp)
.padding(24.dp)
) {
ItemText(
text = "1",
modifier = Modifier
.weight(1f) // 1 の比率
.height(50.dp)
.background(Color.Red)
)
ItemText(
text = "2",
modifier = Modifier
.weight(2f) // 2 の比率
.height(50.dp)
.background(Color.Blue)
)
}
}
Box
BoxはUIコンポーネントをZ軸上に重ねて配置することができるレイアウトコンテナです。子要素の位置は子要素に対してModifier.align(Alignment.TopStart)などを指定することで制御することができます。
@Preview(showBackground = true)
@Composable
fun BoxPreview() {
TestComposeAppTheme {
Box(
Modifier
.width(150.dp)
.height(150.dp)
.padding(24.dp)
) {
ItemText("1", Modifier.align(Alignment.TopStart))
ItemText("2", Modifier.align(Alignment.TopEnd))
ItemText("3", Modifier.align(Alignment.BottomStart))
ItemText("4", Modifier.align(Alignment.BottomEnd))
ItemText("5", Modifier.align(Alignment.Center))
}
}
}
@Composable
fun ItemText(text: String, modifier: Modifier = Modifier) {
Surface(
color = when (text) {
"1" -> MaterialTheme.colorScheme.primary.copy(alpha = 0.5f)
"2" -> MaterialTheme.colorScheme.secondary.copy(alpha = 0.5f)
"3" -> MaterialTheme.colorScheme.tertiary.copy(alpha = 0.5f)
"4" -> MaterialTheme.colorScheme.error.copy(alpha = 0.5f)
else -> MaterialTheme.colorScheme.onBackground.copy(alpha = 0.5f)
},
modifier = modifier
) {
Text(
text,
Modifier
.width(50.dp)
.height(50.dp),
color = MaterialTheme.colorScheme.onPrimary,
textAlign = TextAlign.Center
)
}
}
Box内に配置した要素のZ軸上の重なり具合は先に記述したものが背面に、後に記述したものが前面に表示されます。明示的に重なり順を指定したい場合は.zIndex(zIndex: Float)を使用して制御することができます。zIndexに指定した値が大きいほど前面に表示されます。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。






