今是昨非

今是昨非

日出江花红胜火,春来江水绿如蓝

Flutterレイアウトの基本——Row水平方向のレイアウト

Flutter レイアウトの基本 ——Row 水平レイアウト#

Flutter での水平レイアウトはRowを使用し、要素を水平方向に配置できます。子要素を満たしたい場合は、子要素をExpandedで囲むことができます。

背景#

Rowレイアウトを使用する Widget は、スクロールできません。通常、Row レイアウトを使用する際、デフォルトではすべての子要素の合計が親ビューの幅を超えることはできません。横にスクロールしたい場合は、ListView の使用を検討してください。

Ps:すべての子要素の幅が親ビューのRowの幅を超えると、警告が表示されます。

縦方向のレイアウトが必要な場合は、Columnを使用します。

要素が 1 つだけの場合は、AlignまたはCenterを使用してレイアウトすることを検討してください。

基本紹介#

  • Row の一般的な属性
    • children: 子ビュー
    • textDirection: 子ビューのレイアウト方向
      • TextDirection.ltr: 左から右
      • TextDirection.rtl: 右から左
    • mainAxisAlignment: 子ビューの親ビュー上のレイアウト方法、水平方向のレイアウト
      • MainAxisAlignment.spaceAround: 子ビュー間と子ビューから親ビューまでの距離に間隔を持たせる
      • MainAxisAlignment.center: すべての子ビューを中央に配置
      • MainAxisAlignment.end: すべての子ビューを末尾に配置
      • MainAxisAlignment.spaceBetween: 子ビュー間に等しい間隔を持たせ、親ビューとの間隔は持たせない
      • MainAxisAlignment.spaceEvenly: 子ビュー間と子ビューから親ビューまでの距離に間隔を持たせ、かつ間隔が等しい
      • MainAxisAlignment.start: すべての子ビューを最初に配置

注意:mainAxisAlignment は子要素がExpandedを使用している場合、効果がありません。また、すべての子要素が親ビューの幅を超えた場合も効果がありません。

子要素がExpandedを使用しない場合、子要素の幅は内容に応じて適応されます。つまり、内容が多ければ幅も広くなります。以下はその例です:


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          body: Center(
        child: Row(
          children: [
            Text(
              'First',
              style: TextStyle(backgroundColor: Colors.lightBlueAccent),
              textAlign: TextAlign.center,
            ),
            Text('Second',
                style: TextStyle(backgroundColor: Colors.lightGreenAccent),
                textAlign: TextAlign.center),
            Text('Third',
                style: TextStyle(backgroundColor: Colors.orangeAccent),
                textAlign: TextAlign.center),
          ],
        ),
      )),
    );
  }
}

効果は以下の通りです:

image

注意:上記のTextでは textAlign が設定されていますが、設定内容にかかわらず効果は同じです。

上記の first、second、third を画面の幅いっぱいにしたい場合は、どう設定すればよいでしょうか?簡単です、直接Expandedで囲むだけです。以下はその例です:


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          body: Center(
        child: Row(
          children: [
            Expanded(
                child: Text('First left',
                    style: TextStyle(backgroundColor: Colors.lightBlueAccent),
                    textAlign: TextAlign.left)),
            Expanded(
                child: Text('Second center',
                    style: TextStyle(backgroundColor: Colors.lightGreenAccent),
                    textAlign: TextAlign.center)),
            Expanded(
                child: Text('Third right',
                    style: TextStyle(backgroundColor: Colors.orangeAccent),
                    textAlign: TextAlign.right)),
          ],
        ),
      )),
    );
  }
}

効果は以下の通りです:

image

同様に、上記のTextでは textAlign が設定されていますが、異なる textAlign を設定すると異なる表示効果が得られます。比較すると、Expandedを使用すると、3 つの子要素が画面の幅を均等に分け合っていることがわかります。

実践#

左側に小さなアイコン、中間に長い文書、右側に小さなアイコンがある効果を見てみましょう。

以下のいくつかの状況の表示効果を比較します:

  1. すべての子要素がExpandedを使用していない場合
  2. すべての子要素がExpandedを使用している場合
  3. 中間の長い文書がExpandedを使用し、他の子要素は使用していない場合

すべての子要素がExpandedを使用していない場合#

コードは以下の通りです:


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      body: Center(
        child: Row(children: [
          const FlutterLogo(),
          const Text(
              "Flutterのホットリロードは、迅速かつ簡単に実験、UIの構築、機能の追加、バグの修正を行うのに役立ちます。エミュレーター、シミュレーター、iOSおよびAndroidのハードウェアで、状態を失うことなく、サブ秒のリロード時間を体験してください。"),
          const Icon(Icons.sentiment_satisfied),
        ]),
      ),
    ));
  }
}

効果は以下の通りです:

image

左側のアイコンは表示され、元のサイズのままです。中央の文書は表示されていますが、完了していません。右側のアイコンは見えません。

最初に言ったように、子要素の幅が超えた場合、Flutter は警告を表示します。画像の最右側の赤枠で示された部分が Flutter の警告です。

すべての子要素がExpandedを使用している場合#

コードは以下の通りです:


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      body: Center(
        child: Row(children: [
          Expanded(child: FlutterLogo()),
          Expanded(
              child: const Text(
                  "Flutterのホットリロードは、迅速かつ簡単に実験、UIの構築、機能の追加、バグの修正を行うのに役立ちます。エミュレーター、シミュレーター、iOSおよびAndroidのハードウェアで、状態を失うことなく、サブ秒のリロード時間を体験してください。")),
          Expanded(child: const Icon(Icons.sentiment_satisfied)),
        ]),
      ),
    ));
  }
}

効果は以下の通りです:

image

すべての子要素が表示され、すべての子要素が親要素の幅を均等に分け合っていることがわかります。中央の文書の表示から確認できます。すべての子要素がExpandedで囲まれていると、幅が均等に分配されることが確認されました。

中間の長い文書がExpandedを使用し、他の子要素は使用していない場合#

コードは以下の通りです:


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      body: Center(
        child: Row(children: [
          const FlutterLogo(),
          Expanded(
              child: const Text(
                  "Flutterのホットリロードは、迅速かつ簡単に実験、UIの構築、機能の追加、バグの修正を行うのに役立ちます。エミュレーター、シミュレーター、iOSおよびAndroidのハードウェアで、状態を失うことなく、サブ秒のリロード時間を体験してください。")),
          const Icon(Icons.sentiment_satisfied),
        ]),
      ),
    ));
  }
}

効果は以下の通りです:

image

すべての子要素が表示され、左側と右側のアイコンはそれぞれのサイズで表示され、残りの部分がテキストの表示に使用され、超過することはありません。

参考#

Row Dev Doc
Flutter 無料動画第 3 シーズン - レイアウト

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。