ColumnはJetpack Composeの組み込みComposableコンポーネントで、compose.foundation.layoutパッケージに含まれ、子要素を垂直に、一つずつ配置します。Columnは古いViewシステムの垂直方向のLinearLayoutに相当しますが、それとは異なり、宣言的な記述を使用し、状態の変化に自動的に反応します。Google Android Developers, 2026によると、ColumnはRowやBoxと並んで3つの基本コンテナの一つです。
重要なポイント
Columnはオプションのパラメータ(modifier、verticalArrangement、horizontalAlignment、content)を受け取るComposable関数で、contentはColumnScopeを持つラムダです。Column内では、子のComposable関数が宣言順に上から下へ配置されます。Columnの高さは子の高さの合計にArrangementで指定されたスペースを加えたものです。幅はAlignmentを考慮した最大の子の幅となります。
Columnは不可視のコンテナです。デフォルトでは背景や境界線がありません。背景が必要な場合は、Column自体にModifier.background()を追加してください。LazyColumnとは異なり、Columnはすべての子要素を同時にレンダリングし、仮想化をサポートしません。つまり、Columnは小規模なデータセット(10〜15要素まで)にのみ適しています。長いリストにはLazyColumnを使用してください。
ColumnScopeはColumnのcontentラムダのレシーバーです。Column内でのみ機能する追加のModifier(weight()、align()、alignByBaseline())を提供します。これらのModifierは垂直レイアウトの特性に依存するため、Columnの外では意味がありません。例えば、Modifier.align(Alignment.CenterHorizontally)は子要素をColumnの中央に水平方向に配置します。
VerticalArrangementは要素間の垂直スペースの分配方法を決定します。利用可能な値: Arrangement.Top(デフォルト)、Bottom、Center、SpaceBetween、SpaceEvenly、SpaceAround。Columnの高さが要素の高さの合計より大きい場合、Arrangementが空きスペースを分配します。要素が全高さを占める場合、Arrangementは効果がありません。
HorizontalAlignmentは各子要素の水平方向の配置を設定します。Alignment.Start(LTRのデフォルト)、CenterHorizontally、End。Alignmentは各要素に独立して作用します。ある要素が狭く、別の要素が広い場合、最初の要素は配置されますが、2番目の要素はColumnの境界を超える可能性があります。AlignmentはColumnが固定幅またはfillMaxWidthを持つ場合にのみ機能します。
ColumnのModifier: Columnはコンテナ自体に適用されるModifierを受け入れます。Modifier.fillMaxWidth()、fillMaxHeight()、size()、padding() — すべての標準Modifierが機能します。特別な注意: Modifier.height(IntrinsicSize.Min)は、Intrinsic測定を使用して子要素に基づき最小高さを計算するようColumnに強制します。
@Composable
fun ColumnArrangementDemo() {
Column(
modifier = Modifier.fillMaxSize().background(Color(0xFFF5F5F5)),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("上", modifier = Modifier.background(Color.Cyan))
Text("中", modifier = Modifier.background(Color.Magenta))
Text("下", modifier = Modifier.background(Color.Yellow))
}
}
// IntrinsicSize: Columnはコンテンツに合わせて高さを調整
@Composable
fun IntrinsicColumn() {
Column(
modifier = Modifier
.height(IntrinsicSize.Min)
.width(200.dp)
) {
Text("短いテキスト")
Text("カラム内で折り返される非常に長いテキスト")
}
}
| Arrangement | 動作 |
|---|---|
| Arrangement.Top | 要素が上部に寄せられ、空きスペースは下部 |
| Arrangement.Center | 要素が中央に配置され、スペースは上下均等に分配 |
| Arrangement.SpaceBetween | 最初の要素が上部、最後が下部、残りは均等に配置 |
| Arrangement.SpaceEvenly | すべての要素と端の間が均等な間隔 |
| Arrangement.SpaceAround | 要素間は均等な間隔、端は半分の間隔 |
Modifier.weight()はColumnScopeのModifierで、Column要素間の垂直方向の空きスペースを指定されたウェイトに比例して分配します。Columnが400dpの高さを占め、子要素の合計が100dpの場合、残りの300dpがウェイト要素間で分割されます。weight(2f)の要素はweight(1f)の要素の2倍のスペースを取得します。
fill — weightの2番目のパラメータ: weight(weight: Float, fill: Boolean = true)。fill = true(デフォルト)の場合、要素は利用可能な全高さに引き伸ばされます。fill = falseの場合、要素は自身の本来の高さのみを占め、残りのスペースは空のままです。これは、要素を片側に寄せたいが、weightは空きスペースの分配比率のみを定義する場合に便利です。
Weightの制限: weightは固定高さまたはfillMaxHeight()を持つColumnでのみ機能します。Columnの高さが子要素(wrap content)によって決定される場合、ウェイトは意味を持ちません — 分配する空きスペースがないからです。また、同じ要素でweightをModifier.height()と組み合わせることはできません — 競合が発生し、weightは無視されます。
@Composable
fun WeightedColumn() {
Column(
modifier = Modifier.fillMaxHeight().width(300.dp)
) {
// 高さの1/6を占有(weight 1、合計1+2+3=6)
Box(
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.background(Color.Red)
)
// 高さの2/6を占有
Box(
modifier = Modifier
.weight(2f)
.fillMaxWidth()
.background(Color.Green)
)
// 高さの3/6を占有
Box(
modifier = Modifier
.weight(3f)
.fillMaxWidth()
.background(Color.Blue)
)
}
}
Columnはすべての子要素を即座にレンダリングします。要素が10〜15を超える場合、Columnはコンポジションと測定に大きな負荷をかけます。一方、LazyColumnは表示されている要素のみをレンダリングし、非表示の要素を再利用します。長いリスト、数千要素のリスト、無限リスト、チャットにはLazyColumnが必須です。
Columnが適している場合: フォーム画面(3〜10フィールド)、プロフィールカード、アイコン付きの垂直カラム、メニュー。ColumnはIntrinsicSizeもサポートしており、アダプティブな高さに便利です。さらに、Columnはデバッグが容易です — 仮想化がないため、すべての要素がLayout Inspectorで表示されます。静的UIにはColumnが適切な選択です。
LazyColumnが提供するもの: アイテムキャッシング、キーベースの識別、追加/削除のアニメーション(animateItemPlacement)、スティッキーヘッダー。リストに異なるタイプの要素(異なるviewType)が含まれる場合は、itemsでsealed classを使用したLazyColumnを使用してください。Columnはスティッキーヘッダーをサポートしていません(スクロール可能なColumnでエミュレーションする必要があります)。また、LazyColumnはGridCellsを使用する際にLazyVerticalGridをサポートします。
| 基準 | Column | LazyColumn |
|---|---|---|
| 要素数 | 最大10〜15 | 任意 |
| パフォーマンス | 常にすべてをレンダリング | 表示のみ + バッファ |
| スクロール | Modifier.verticalScroll経由 | 組み込み |
| IntrinsicSize | 対応 | 非対応 |
| スティッキーヘッダー | なし(エミュレーション) | あり(stickyHeader) |
| 要素アニメーション | 組み込みなし | animateItemPlacement |
ユーザープロフィール画面を見てみましょう。ここではColumnがアバター、名前、自己紹介、アクションボタンのメインコンテナとして使用されています。IntrinsicSize.Minを使用したColumnはコンテンツに合わせて調整され、weightはセクション間のスペース配分に使用されます。
@Composable
fun UserProfileCard(name: String, bio: String) {
Card(
modifier = Modifier.fillMaxWidth().padding(16.dp),
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
) {
Column(
modifier = Modifier.fillMaxWidth().padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
// アバター
Icon(
imageVector = Icons.Default.AccountCircle,
contentDescription = "Avatar",
modifier = Modifier.size(64.dp)
)
// 名前
Text(name, style = MaterialTheme.typography.headlineSmall)
// 自己紹介
Text(bio, style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.padding(top = 4.dp))
// アクションボタン
Row(
horizontalArrangement = Arrangement.spacedBy(12.dp),
modifier = Modifier.padding(top = 12.dp)
) {
Button(onClick = { }) { Text("メッセージ") }
OutlinedButton(onClick = { }) { Text("フォロー") }
}
}
}
}
この例では、Columnは要素間の均等な間隔にArrangement.spacedBy(8.dp)を使用しています。horizontalAlignment = CenterHorizontallyはアバター、名前、自己紹介を中央揃えにします。Column内のRowは、1行のボタン用のネストされたコンテナです。Column(垂直配置)とRow(水平配置)のこの組み合わせは、ComposeでのUI構築の典型的なパターンです。
よくある質問
Columnはすべての子要素を一度にレンダリングするため、100要素以上でFPSが低下します。LazyColumnは表示要素とバッファ(通常3〜5画面分)のみをレンダリングします。3〜10要素の静的画面では、仮想化のオーバーヘッドがないためColumnの方が高速です。
ColumnにModifier.verticalScroll(rememberScrollState())を追加します。これによりColumnはスクロール可能になりますが、仮想化は提供されません — すべての要素は依然として一度にレンダリングされます。長いスクロール可能なリストにはLazyColumnを使用してください。
はい、Row/Columnのネストは一般的な手法です。2つのコンテナを組み合わせることで、複雑なグリッドを構築できます。ただし、不必要な深いネスト(4レベル以上)は避けてください — LayoutNodeの測定回数が増加し、コンポジションが遅くなります。
各子要素にModifier.fillMaxWidth()を使用します。ColumnがModifier.fillMaxWidth()を持つ場合、fillMaxWidth()を持つすべての子要素が全幅に引き伸ばされます。代替案: Columnが固定コンテナ内にある場合は、ColumnScopeでModifier.weight(1f)を使用します。
Arrangement.spacedBy(space)は隣接する2つの要素間に固定の間隔を追加します。SpaceBetween/SpaceAroundとは異なり、spacedByは要素を引き伸ばしません — 間隔は固定で、残りのスペースはColumnの末尾に残ります。spacedByは最初の要素の前や最後の要素の後には間隔を追加しません。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。