Flutter レイアウト基礎

レイアウトは Flutter UI 開発の中核となる概念です。

このセクションでは、Row、Column、Stack、Flex など、最もよく使われるレイアウト Widget を紹介します。


レイアウト Widget の概要

Flutter は豊富なレイアウト Widget を提供しており、さまざまな UI デザインのニーズに対応できます。

Widget用途
Row子 Widget を水平に配置する
Column子 Widget を垂直に配置する
Stack子 Widget を重ねて配置する
Flex柔軟な線形レイアウト(Row/Column の基底クラス)
GridViewグリッドレイアウト
ListViewリストレイアウト

Row - 水平レイアウト

Row は子 Widget を水平方向に配置するために使います。

例:Row の基本的な使い方

// 3つのアイコンを水平に配置
Row(
  children: [
    Icon(Icons.home, color: Colors.blue),
    Icon(Icons.search, color: Colors.green),
    Icon(Icons.settings, color: Colors.grey),
  ],
)

// 間隔付きの Row
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,  // 主軸の整列方法
  children: [
    Icon(Icons.home, color: Colors.blue),
    Icon(Icons.search, color: Colors.green),
    Icon(Icons.settings, color: Colors.grey),
  ],
)

mainAxisAlignment - 主軸の整列

值説明
MainAxisAlignment.start左揃え(デフォルト)
MainAxisAlignment.center中央揃え
MainAxisAlignment.end右揃え
MainAxisAlignment.spaceBetween両端揃え、アイテム間の間隔は等しい
MainAxisAlignment.spaceEvenlyアイテム間と両端の間隔が等しい
MainAxisAlignment.spaceAroundアイテム間の間隔は等しく、両端の間隔より大きい

Column - 垂直レイアウト

Column は子 Widget を垂直方向に配置するために使います。

例:Column の基本的な使い方

// 3つのテキストを垂直に配置
Column(
  children: [
    Text('1行目', style: TextStyle(fontSize: 20)),
    Text('2行目', style: TextStyle(fontSize: 20)),
    Text('3行目', style: TextStyle(fontSize: 20)),
  ],
)

// 間隔と整列を設定した Column
Column(
  mainAxisAlignment: MainAxisAlignment.center,  // 垂直方向の中央揃え
  crossAxisAlignment: CrossAxisAlignment.start,  // 水平方向の左揃え
  children: [
    Text('タイトル', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
    const SizedBox(height: 8),
    Text('内容内容内容'),
    const SizedBox(height: 8),
    Text('下部の説明'),
  ],
)

crossAxisAlignment - 交差軸の整列

值説明
CrossAxisAlignment.start上揃え/左揃え
CrossAxisAlignment.center中央揃え
CrossAxisAlignment.end下揃え/右揃え
CrossAxisAlignment.stretch引き伸ばして親コンテナを満たす

Expanded と Flexible

Expanded と Flexible は、子 Widget に残りのスペースを埋めさせるために使います。

例:Expanded の使い方

// 固定幅 + 可変幅
Row(
  children: [
    // 固定幅 100
    Container(width: 100, height: 50, color: Colors.red),
    // 残りのスペースを占有
    Expanded(
      child: Container(height: 50, color: Colors.green),
    ),
    // 固定幅 50
    Container(width: 50, height: 50, color: Colors.blue),
  ],
)

// 比率を割り当て
Row(
  children: [
    // 1 の割合
    Expanded(
      flex: 1,
      child: Container(height: 50, color: Colors.red),
    ),
    // 2 の割合
    Expanded(
      flex: 2,
      child: Container(height: 50, color: Colors.green),
    ),
    // 1 の割合
    Expanded(
      flex: 1,
      child: Container(height: 50, color: Colors.blue),
    ),
  ],
)

Stack - 重ね合わせレイアウト

Stack は子 Widget を重ね合わせるために使います。浮動要素やレイヤー合成などの効果を実現するためによく使われます。

例:Stack の使い方

// 基本的な Stack
Stack(
  children: [
    // 最下層:背景画像
    Container(
      width: 200,
      height: 200,
      color: Colors.blue,
    ),
    // 中間層:半透明のオーバーレイ
    Container(
      width: 180,
      height: 180,
      color: Colors.white.withOpacity(0.5),
    ),
    // 最上層:テキスト
    const Center(
      child: Text(
        '重ね合わせコンテンツ',
        style: TextStyle(color: Colors.white, fontSize: 24),
      ),
    ),
  ],
)

// 位置指定付きの Stack
Stack(
  children: [
    Container(color: Colors.grey[300]),
    // 右上に配置
    Positioned(
      right: 10,
      top: 10,
      child: Icon(Icons.close, color: Colors.red),
    ),
    // 左下に配置
    Positioned(
      left: 10,
      bottom: 10,
      child: Text('左下のテキスト'),
    ),
  ],
)

Padding と Margin

Padding と Margin を使って、要素の内側の余白と外側の余白を制御します。

例:Padding と Margin

// Padding を使って内側の余白を設定
Padding(
  padding: const EdgeInsets.all(16.0),  // 四方すべて16ピクセル
  child: Text('内側の余白があるテキスト'),
)

// 各辺を個別に設定
Padding(
  padding: EdgeInsets.only(
    left: 10,
    right: 20,
    top: 5,
    bottom: 5,
  ),
  child: Text('カスタム内側の余白'),
)

// EdgeInsets.symmetric で対称な余白を設定
Padding(
  padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
  child: Text('水平16、垂直8'),
)

// Container で margin と padding を組み合わせる
Container(
  margin: const EdgeInsets.all(10),  // 外側の余白
  padding: const EdgeInsets.all(16),  // 内側の余白
  decoration: BoxDecoration(
    color: Colors.blue[100],
    borderRadius: BorderRadius.circular(8),
  ),
  child: Text('コンテナの内容'),
)

Scaffold と AppBar

Scaffold は Material Design の基本的なページ構造を提供し、AppBar は上部のアプリケーションバーです。

例:Scaffold の基本構造

// Material Design のページ用スキャフォールド
Scaffold(
  // 上部のアプリケーションバー
  appBar: AppBar(
    title: const Text('マイアプリ'),
    backgroundColor: Colors.blue,
    elevation: 4,  // 影の深さ
    actions: [
      IconButton(
        icon: const Icon(Icons.search),
        onPressed: () {},
      ),
      IconButton(
        icon: const Icon(Icons.settings),
        onPressed: () {},
      ),
    ],
  ),
  // ページのメインコンテンツ
  body: const Center(
    child: Text('ページのメインコンテンツ'),
  ),
  // フローティングアクションボタン
  floatingActionButton: FloatingActionButton(
    onPressed: () {},
    child: const Icon(Icons.add),
  ),
  // 下部のナビゲーションバー
  bottomNavigationBar: BottomNavigationBar(
    items: const [
      BottomNavigationBarItem(icon: Icon(Icons.home), label: 'ホーム'),
      BottomNavigationBarItem(icon: Icon(Icons.search), label: '検索'),
      BottomNavigationBarItem(icon: Icon(Icons.person), label: 'マイページ'),
    ],
  ),
)
その他の拡張