【Flutter】React Native エンジニアが学ぶ レイアウト

2022/07/25に公開

普段は業務で React Native を使用したアプリケーションを作成しているので、そこと対比しつつ学んでいます。

FlutterのUIレイアウト

React Native ではWebで培ったHTML/CSSの知識を生かしてマークアップできます。Flutterでは若干勝手が異なります。

  • div や View の代わりに Container を使用する
  • Column / Row で レイアウトを調整できる
  • Expanded で flex する
  • Stack で要素を重ねる

Container

React / React Native でいう divView に似ています。Container には高さや横幅、背景色など様々な設定ができます。UIの基本的な単位となるものです。

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "MyApp",
      home: Scaffold(
        body: Center(
          child: Container(
            color: Colors.blue,
            width: 300.0,
            height: 300.0,
            child: Text("Hello World!"),
            alignment: Alignment.center,
          ),
        ),
      ),
    );
  }
}

Row / Column

Row/Column を利用することで、Gridレイアウトが可能です。
ポイントとしては、mainAxisAlignment を使用して 列や行を画面のどの位置に配分するかを指定することです。
これはWeb や React Native でいうと justifyContentalighnItems の設定と同様です。

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "MyApp",
      home: Container(
        child: Row(  // 行
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,  // 他にstart、end、spaceAroundなど
          children: <Widget>[
            Column(  // 列
              mainAxisAlignment: MainAxisAlignment.center,  // 中央に配置
              children: <Widget>[
                Container( color: Colors.blue, width: 100, height:100 ),
                Container( color: Colors.red, width: 100, height:100 ),
                Container( color: Colors.yellow, width: 100, height:100 ),
              ],
            ),
            Column(  // 列
              mainAxisAlignment: MainAxisAlignment.center,  // 中央に配置
              children: <Widget>[
                Container( color: Colors.green, width: 100, height:100 ),
                Container( color: Colors.orange, width: 100, height:100 ),
                Container( color: Colors.white, width: 100, height:100 ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

Expanded

これはWeb や React Native でいうと flex の設定と同様です。

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "MyApp",
      home: Container(
        child: Row(
          children: <Widget>[
            Expanded(  // 引き延ばして表示
                flex: 1,
                child:Container( color: Colors.red)
            ),
            Expanded(
              flex: 2,
              child:Container( color: Colors.green),
            ),
            Expanded(
              child:Container( color: Colors.blue),
              flex: 3,
            ),
          ],
        ),
      ),
    );
  }
}

Stack

要素同士を重ねる場合は Stackを使用します。配列内の最初の要素が一番下、最後の要素が一番上になります。

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(
              title: Text("MyApp"),
            ),
            body: Stack(  // 重ねて表示
              children: <Widget>[
                Container(
                    width: 200,
                    height: 200,
                    color:Colors.red
                ),
                Container(
                  width: 100,
                  height: 120,
                  color: Colors.green,
                ),
                Container(
                  width: 50,
                  height: 70,
                  color: Colors.blue,
                )
              ],
            )
        )
    );
  }
}

参考

https://www.udemy.com/share/103yEU3@knV-rLlkFK0iZ-cTMnk1QnD8nzBy871G0ZUt6fgoP2W298h4nj2L7Uz2HS-NkqwJ/

Discussion