【Flutter】画面レイアウトのコーディング手順について(前編)

モバイルアプリ開発エンジニアの木村です。
弊社では見積書アプリ検索ランキング1位の見積・請求書作成アプリ『ジムー』をはじめとする、モバイルアプリ開発を行っておりまして私は主にアプリの開発を担当しております。

本記事では私がFlutterで画面レイアウトをコーディングしていく際にどのような手順で考えているかを共有していきます。
なので対象者はFlutterを始めてみたい方や触り始めの方向けになります。

はじめに

まずは作成したい画面のレイアウトを確認してみましょう。
確認する際にどのようなパーツがどのような位置に配置されているのか、どのように動くのかも合わせて確認するとコーディングしやすいと思います。

今回は例として以下のようなログイン画面を見ていきます。
本記事ではログイン画面のそれぞれのパーツの表示位置の設定を解説していきます。
(後半の記事でテキストやボタンの設定を解説します。)

レイアウトのコーディング

前章のログイン画面のレイアウトをいくつかの手順に分けて実際にコーディングしていきます。

(1) 画面全体の余白を設定する

初めに画面全体を確認してパーツの上下左右の余白を確認しましょう。
以下の図のようにパーツが表示されない余白の部分があるかと思います。

まずはこちらの設定を追加していきます。
余白を設定できるWidgetとして「Container」というWidgetがあるので追加していきます。
追加した「Container」に余白部分としてmarginを設定しましょう。

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        margin: const EdgeInsets.only(left: 30, top: 100, right: 30, bottom: 50),
      ),
    );
  }

(2) 各パーツの並び方(縦・横)を設定する

次に確認していく観点として画面のパーツがどの方向に並んでいるか(縦もしくは横)という点になります。
今回の画面だと全てのパーツが縦に並んでいることが分かると思います。
Flutterでは縦にパーツを並べる際は「Column」というWidgetを使用するのでbuildメソッド内の以下の位置に「Column」というWidgetを追加しましょう。

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        margin: const EdgeInsets.only(left: 30, top: 100, right: 30, bottom: 50),
        child: Column(
        ),
      ),
    );
  }

(3) パーツの揃え方(左右・中央)を設定する

ログイン画面全体を見ると多くのパーツは画面左始まりで置かれているので(2)で追加した「Column」に左寄せという設定を追加していきましょう。
左寄せの設定は「crossAxisAlignment」に「CrossAxisAlignment.start」という指定の方法になります。

Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        margin: const EdgeInsets.only(left: 30, top: 100, right: 30, bottom: 50),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
        ),
      ),
    );
  }

(4) 画面にパーツを追加する

ログイン画面全体を見るとパーツが8個並んでいると思います。
(ログインテキスト・ログインID入力欄・ログインボタンなど)

ひとまずパーツを8個並べるために「Column」の子要素として「Continer」を8個追加していきます。
(今回はわかりやすいようにサイズ・色・マージンを設定しています)

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        margin: const EdgeInsets.only(left: 30, top: 100, right: 30, bottom: 50),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Container(
              margin: const EdgeInsets.all(5),
              height: 50,
              width: 200,
              color: Colors.orangeAccent,
            ),
            ///    省略      ///
            Container(
              margin: const EdgeInsets.all(5),
              height: 50,
              width: 200,
              color: Colors.orangeAccent,
            ),
          ],
        ),
      ),
    );
  }

(5) 特定のパーツの揃え方(左右・中央)を設定する

(3)では基本的にパーツは左から並んでいると記載しましたが「ログイン」という文字は画面の中心に表示されていました。

全体にではなく特定のパーツだけ表示位置を変更したい場合はそのWidgetに対して横並びを設定できる「Row」というWidgetを追加します。
そして「Row」の「mainAxisAlignment」に「MainAxisAlignment.center」を設定することで特定のパーツだけ画面に対して中央寄せを設定をすることできます。

///   省略   ///
child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Container(
                  margin: const EdgeInsets.all(5),
                  height: 50,
                  width: 200,
                  color: Colors.orangeAccent,
                ),
              ],
            ),
///   省略   ///

(6) 各パーツのサイズ・余白を設定する

(5)ではタイトルの「ログイン」に当たるパーツだけ調整しましたがこの章ではその他のパーツのサイズと余白の調整をしていきます。

各パーツのサイズは「width」と「height」で調整可能となります。
ログインの入力欄のように可能な限り横幅いっぱいに表示したい場合は「double.infinity」を設定します。

余白は先ほど使用した「Container」の「margin」でも設定可能ですが今回は分かりやすいようにするため「SizedBox」のパーツを入れています。

(1)~(6)の手順を進めてきて現時点で全体のソースコードと表示しているレイアウトは以下になります。

Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        margin: const EdgeInsets.only(left: 30, top: 100, right: 30, bottom: 50),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Container(
                  margin: const EdgeInsets.all(5),
                  height: 50,
                  width: 200,
                  color: Colors.orangeAccent,
                ),
              ],
            ),
            const SizedBox(
              height: 40,
            ),
            Container(
              margin: const EdgeInsets.all(5),
              height: 40,
              width: 200,
              color: Colors.orangeAccent,
            ),
            Container(
              margin: const EdgeInsets.all(5),
              height: 50,
              width: double.infinity,
              color: Colors.orangeAccent,
            ),
            const SizedBox(
              height: 20,
            ),
            Container(
              margin: const EdgeInsets.all(5),
              height: 40,
              width: 200,
              color: Colors.orangeAccent,
            ),
            Container(
              margin: const EdgeInsets.all(5),
              height: 50,
              width: double.infinity,
              color: Colors.orangeAccent,
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                Container(
                  margin: const EdgeInsets.all(5),
                  height: 30,
                  width: 200,
                  color: Colors.orangeAccent,
                ),
              ],
            ),
            const SizedBox(
              height: 40,
            ),
            Container(
              margin: const EdgeInsets.all(5),
              height: 50,
              width: double.infinity,
              color: Colors.orangeAccent,
            ),
            Container(
              margin: const EdgeInsets.all(5),
              height: 50,
              width: double.infinity,
              color: Colors.orangeAccent,
            ),
          ],
        ),
      ),
    );
  }

まとめ

これでログイン画面のレイアウトの大枠は完成しました!

仮にはなりますが表示したい位置にオレンジの枠を設置することができたと思います。
後編の記事でオレンジ色の枠にしていた箇所をそれぞれ文字や入力欄、ボタンを設定しログイン画面のデザインを完成させていきたいと思います。

ここまで読んでくださり、ありがとうございました。
後編を投稿するまで少々お待ちください。

エフアンドエムネット株式会社では一緒に働く仲間を募集しています!
詳しくは採用ページをご覧ください!