<

建物のレイアウト

これは、Flutter でレイアウトを構築するためのガイドです。 次のアプリのレイアウトを構築します。

The finished app
完成したアプリ

このガイドでは、一歩下がって Flutter について説明します。 レイアウトへのアプローチと、単一のウィジェットを配置する方法を示します。 画面上。ウィジェットの配置方法について議論した後 最も一般的なものは、水平方向と垂直方向です。 レイアウトウィジェットはカバーされています。

レイアウトメカニズムの「全体像」を理解したい場合は、 皮切りにFlutter のレイアウトへのアプローチ

ステップ 0: アプリのベースコードを作成する

必ず設定あなたの環境、 次に、次の操作を行います。

  1. 新しい Flutter アプリを作成する
  2. の内容を置き換えますlib/main.dart次のコードで:

    lib/main.dart (すべて)
    import 'package:flutter/material.dart';
    
    void main() => runApp(const MyApp());
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter layout demo',
          home: Scaffold(
            appBar: AppBar(
              title: const Text('Flutter layout demo'),
            ),
            body: const Center(
              child: Text('Hello World'),
            ),
          ),
        );
      }
    }

ステップ 1: レイアウトを図示する

最初のステップは、レイアウトを基本要素に分解することです。

  • 行と列を識別します。
  • レイアウトにグリッドは含まれていますか?
  • 重複する要素はありますか?
  • UI にはタブが必要ですか?
  • 位置合わせ、パディング、または境界線が必要な領域に注目してください。

まず、より大きな要素を特定します。この例では、 画像、2 行、テキスト ブロックの 4 つの要素が 1 列に配置されます。

Column elements (circled in red)
列要素 (赤丸で囲った部分)

次に、各行を図表にします。最初の行はタイトルと呼ばれます セクションには、テキストの列、星のアイコン、 そして数字。その最初の子である列には 2 行のテキストが含まれます。 最初の列は多くのスペースを必要とするため、 展開されたウィジェット。

Title section

2 行目は「ボタン」セクションと呼ばれ、次の行もあります。 3 つの子: 各子はアイコンとテキストを含む列です。

Button section

レイアウトを図示したら、最も簡単なのは、 ボトムアップのアプローチで実装します。 深くネストされたレイアウト コードによる視覚的な混乱を最小限に抑えるために、 実装の一部を変数と関数に配置します。

ステップ 2: タイトル行を実装する

まず、タイトルセクションの左側の列を作成します。 次のコードを先頭に追加しますbuild()の方法MyAppクラス:

lib/main.dart (タイトルセクション)
Widget titleSection = Container(
  padding: const EdgeInsets.all(32),
  child: Row(
    children: [
      Expanded(
        /*1*/
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            /*2*/
            Container(
              padding: const EdgeInsets.only(bottom: 8),
              child: const Text(
                'Oeschinen Lake Campground',
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
            Text(
              'Kandersteg, Switzerland',
              style: TextStyle(
                color: Colors.grey[500],
              ),
            ),
          ],
        ),
      ),
      /*3*/
      Icon(
        Icons.star,
        color: Colors.red[500],
      ),
      const Text('41'),
    ],
  ),
);
  1. を置くColumnの中でExpandedウィジェットのストレッチ 列に行内の残りの空き領域をすべて使用します。 の設定crossAxisAlignment財産をCrossAxisAlignment.start列を次の位置に配置します 行の始まり。
  2. テキストの最初の行をContainerパディングを追加できるようになります。 2番目の子供は、Columnもテキストであり、灰色で表示されます。
  3. タイトル行の最後の 2 つの項目は星アイコンです。 赤く塗られ、「41」の文字。行全体が入っています あるContainer各エッジに沿って 32 ピクセルずつパディングされます。 次のように、タイトル セクションをアプリ本体に追加します。
{../base → step2}/lib/main.dart
@@ -14,11 +48,​​13 @@
14
48
  戻りマテリアルApp(
15
49
  タイトル: 'Flutter レイアウトのデモ',
16
50
  ホーム: 足場(
17
51
  アプリバー: アプリバー(
18
52
  title: const Text('Flutter レイアウト デモ'),
19
53
  )、
20
- 体:const センター(
21
- 子供:Text('Hello World'),
54
+ 体:(
55
+ 子供:[
56
+ タイトルセクション、
57
+ ]、
22
58
  )、
23
59
  )、
24
60
  );

ステップ 3: ボタン行を実装する

ボタンセクションには、同じものを使用する 3 つの列が含まれています。 レイアウト - テキスト行の上にアイコンを配置します。 この行の列は等間隔に配置されており、 テキストとアイコンは原色でペイントされます。

各列を構築するコードはほぼ同じなので、 という名前のプライベートヘルパーメソッドを作成しますbuildButtonColumn()、 それは色を取り、IconText、 そして、指定された色でペイントされたウィジェットを含む列を返します。

lib/main.dart (_buildButtonColumn)
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    // ···
  }

  Column _buildButtonColumn(Color color, IconData icon, String label) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Icon(icon, color: color),
        Container(
          margin: const EdgeInsets.only(top: 8),
          child: Text(
            label,
            style: TextStyle(
              fontSize: 12,
              fontWeight: FontWeight.w400,
              color: color,
            ),
          ),
        ),
      ],
    );
  }
}

この関数はアイコンを列に直接追加します。 テキストはContainer上部のみのマージンを使用して、 テキストをアイコンから分離します。

を呼び出して、これらの列を含む行を構築します。 関数と色を渡す、Icon、およびテキスト固有の そのコラムに。主軸に沿って列を整列させます 使用してMainAxisAlignment.spaceEvenlyを手配する 各列の前、列の間、後のスペースを均等に解放します。 次のコードをすぐ下に追加します。titleSection内の宣言build()方法:

lib/main.dart (ボタンセクション)
Color color = Theme.of(context).primaryColor;

Widget buttonSection = Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    _buildButtonColumn(color, Icons.call, 'CALL'),
    _buildButtonColumn(color, Icons.near_me, 'ROUTE'),
    _buildButtonColumn(color, Icons.share, 'SHARE'),
  ],
);

本体にボタンセクションを追加します。

{ステップ2 → ステップ3}/lib/main.dart
@@ -48,3 +59,3 @@
48
59
  戻りマテリアルApp(
49
60
  タイトル: 'Flutter レイアウトのデモ',
50
61
  ホーム: 足場(
@@ -54,8 +65,9 @@
54
65
  本文: 列(
55
66
  子供: [
56
67
  タイトルセクション、
68
+ ボタンセクション、
57
69
  ]、
58
70
  )、
59
71
  )、
60
72
  );
61
73
  }

ステップ 4: テキスト セクションを実装する

テキストセクションを変数として定義します。テキストを入れます でContainer各エッジに沿ってパディングを追加します。 次のコードをすぐ下に追加します。buttonSection宣言:

lib/main.dart (テキストセクション)
Widget textSection = const Padding(
  padding: EdgeInsets.all(32),
  child: Text(
    'Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese '
    'Alps. Situated 1,578 meters above sea level, it is one of the '
    'larger Alpine Lakes. A gondola ride from Kandersteg, followed by a '
    'half-hour walk through pastures and pine forest, leads you to the '
    'lake, which warms to 20 degrees Celsius in the summer. Activities '
    'enjoyed here include rowing, and riding the summer toboggan run.',
    softWrap: true,
  ),
);

設定することによりsoftwraptrue に設定すると、テキスト行が列幅いっぱいになるまで表示されます。 単語境界での折り返し。

テキストセクションを本文に追加します。

{ステップ3 → ​​ステップ4}/lib/main.dart
@@ -59,3 +72,3 @@
59
72
  戻りマテリアルApp(
60
73
  タイトル: 'Flutter レイアウトのデモ',
61
74
  ホーム: 足場(
@@ -66,6 +79,7 @@
66
79
  子供: [
67
80
  タイトルセクション、
68
81
  ボタンセクション、
82
+ テキストセクション、
69
83
  ]、
70
84
  )、
71
85
  )、

ステップ 5: 画像セクションを実装する

4 つの列要素のうち 3 つが完了しました。 画像だけを残して。画像ファイルを例に追加します。

  • を作成しますimagesプロジェクトの先頭にあるディレクトリ。
  • 追加lake.jpg
  • を更新しますpubspec.yamlを含めるファイルassets鬼ごっこ。 これにより、コードで画像を使用できるようになります。

    {ステップ4 → ステップ5}/pubspec.yaml
    @@ -18,3 +18,5 @@
    18
    18
      はためく:
    19
    19
      使用材料設計: true
    20
    + 資産:
    21
    + - 画像/湖.jpg

これで、コードから画像を参照できるようになります。

{ステップ4 → ステップ5}/lib/main.dart
@@ -77,6 +77,12 @@
77
77
  )、
78
78
  本文: 列(
79
79
  子供: [
80
+ 画像.アセット(
81
+ '画像/湖.jpg',
82
+ 幅: 600、
83
+ 高さ: 240、
84
+ フィット: BoxFit.cover、
85
+ )、
80
86
  タイトルセクション、
81
87
  ボタンセクション、
82
88
  テキストセクション、

BoxFit.cover画像が次のようにすることをフレームワークに指示します。 できるだけ小さくしますが、レンダー ボックス全体をカバーします。

ステップ 6: 最後の仕上げ

この最後のステップでは、すべての要素を配置します。ListViewではなく、Column、なぜならListViewアプリ実行時のアプリ本体のスクロールをサポートします 小さなデバイスで。

{ステップ5 → ステップ6}/lib/main.dart
@@ -72,13 +77,13 @@
72
77
  戻りマテリアルApp(
73
78
  タイトル: 'Flutter レイアウトのデモ',
74
79
  ホーム: 足場(
75
80
  アプリバー: アプリバー(
76
81
  title: const Text('Flutter レイアウト デモ'),
77
82
  )、
78
- 体:(
83
+ 体:リストビュー(
79
84
  子供: [
80
85
  画像.アセット(
81
86
  '画像/湖.jpg',
82
87
  幅: 600、
83
88
  高さ: 240、
84
89
  フィット: BoxFit.cover、

ダーツコード: main.dart
画像: 画像
パブスペック: pubspec.yaml

それでおしまい!アプリをホットリロードすると、 と同じアプリのレイアウトが表示されるはずです。 このページの上部にあるスクリーンショット。

次のようにして、このレイアウトにインタラクティブ性を追加できます。Flutter アプリにインタラクティブ性を追加する