Column: Composeにおける垂直配置とコンテナ設定

著者: IT Sectr 公開日: 2026-06-28 読了時間: 8 分

ColumnはJetpack Composeの組み込みComposableコンポーネントで、compose.foundation.layoutパッケージに含まれ、子要素を垂直に、一つずつ配置します。Columnは古いViewシステムの垂直方向のLinearLayoutに相当しますが、それとは異なり、宣言的な記述を使用し、状態の変化に自動的に反応します。Google Android Developers, 2026によると、ColumnはRowやBoxと並んで3つの基本コンテナの一つです。

重要なポイント

  • ColumnはArrangementとAlignmentの設定で要素を垂直に配置します
  • Arrangementは要素間の垂直スペースの分配を定義します
  • AlignmentはColumn内の各要素の水平方向の配置を設定します
  • Weightは空きスペースを要素間で比例配分します
  • IntrinsicSizeにより、Columnは子の最小/最大幅に合わせてサイズを調整できます

Jetpack ComposeにおけるColumnとは

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の中央に水平方向に配置します。

Columnのパラメータ: Arrangement, Alignment, Modifier

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に強制します。

kotlin
@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要素間は均等な間隔、端は半分の間隔

Column weight: 要素間のスペース配分

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は無視されます。

kotlin
@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 vs LazyColumn: それぞれの使い分け

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をサポートします。

基準ColumnLazyColumn
要素数最大10〜15任意
パフォーマンス常にすべてをレンダリング表示のみ + バッファ
スクロールModifier.verticalScroll経由組み込み
IntrinsicSize対応非対応
スティッキーヘッダーなし(エミュレーション)あり(stickyHeader)
要素アニメーション組み込みなしanimateItemPlacement

Columnの実用的な使用例

ユーザープロフィール画面を見てみましょう。ここではColumnがアバター、名前、自己紹介、アクションボタンのメインコンテナとして使用されています。IntrinsicSize.Minを使用したColumnはコンテンツに合わせて調整され、weightはセクション間のスペース配分に使用されます。

kotlin
@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とLazyColumnの違いは何ですか?

Columnはすべての子要素を一度にレンダリングするため、100要素以上でFPSが低下します。LazyColumnは表示要素とバッファ(通常3〜5画面分)のみをレンダリングします。3〜10要素の静的画面では、仮想化のオーバーヘッドがないためColumnの方が高速です。

Columnをスクロール可能にするには?

ColumnにModifier.verticalScroll(rememberScrollState())を追加します。これによりColumnはスクロール可能になりますが、仮想化は提供されません — すべての要素は依然として一度にレンダリングされます。長いスクロール可能なリストにはLazyColumnを使用してください。

Rowの中にColumn、Columnの中にRowをネストできますか?

はい、Row/Columnのネストは一般的な手法です。2つのコンテナを組み合わせることで、複雑なグリッドを構築できます。ただし、不必要な深いネスト(4レベル以上)は避けてください — LayoutNodeの測定回数が増加し、コンポジションが遅くなります。

Column内のすべての要素の幅を同じにするには?

各子要素にModifier.fillMaxWidth()を使用します。ColumnがModifier.fillMaxWidth()を持つ場合、fillMaxWidth()を持つすべての子要素が全幅に引き伸ばされます。代替案: Columnが固定コンテナ内にある場合は、ColumnScopeでModifier.weight(1f)を使用します。

ColumnでのspacedByの動作は?

Arrangement.spacedBy(space)は隣接する2つの要素間に固定の間隔を追加します。SpaceBetween/SpaceAroundとは異なり、spacedByは要素を引き伸ばしません — 間隔は固定で、残りのスペースはColumnの末尾に残ります。spacedByは最初の要素の前や最後の要素の後には間隔を追加しません。

まとめ

  • Column — 要素を上から下に配置するComposeの基本的な垂直コンテナ
  • Arrangementがスペース配分を制御(Top, Center, SpaceBetween, spacedBy)
  • Alignmentが各子要素の水平配置を設定
  • Weightが空きスペースを要素間で比例配分
  • Column vs LazyColumn: 3〜10要素にはColumn、長いリストにはLazyColumn
  • IntrinsicSizeでColumnが子の最小測定に合わせて高さを調整可能
  • 推奨: 各要素にpaddingを使う代わりに、要素間の間隔にはspacedByを使用

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください