Flutter公式ドキュメントで勉強した内容を要約したものです。

Hello Flutter!

まずはプロジェクトを作成してmain.dartファイルを編集する。

前回作成したfirst_sampleを使っても良いし、次のコマンドで新しいプロジェクトを作成しても問題ない。

1
2
3
flutter create first_sample
cd first_sample
code .

/lib/main.dartファイルを開き、main関数以外は削除し、次のコードを入力する。

1
2
3
4
5
6
7
8
9
10
11
12
import 'package:flutter/material.dart';

void main() {
  runApp(
    const Center(
      child: Text(
        'Hello, Flutter!',
        textDirection: TextDirection.ltr,
      ),
    ),
  );
}

次の上のコードをiOSシミュレーターで実行した画面だ。

iOS Simulator

Flutterは全てウィジェットで構成されていてウィジェットはツリー(Tree)構造になっている。

runAppはウィジェットをパラメータにしてパラメータのウィジェットはツリーのルートになる。このコードではCenterウィジェットがルートでその枝がTextウィジェットになるのだ。

このサンプルは簡単に文字列を表示するものであるが、アプリを作成するときにはウィジェットの組み合わせになるのでウィジェットの状態を管理するかどうかによってStatelessWidgetまたはStatefulWidgetを使う。ステートがあるかどうか、静的か動的かだ。

Basic Widget

よく使われる基本的なウィジェットをいくつか使ってみる。

Text

上のサンプルでも使ったが、スタイル適用可能なテキストが作成できるウィジェットだ。

Row, Column

フレックス・ウィジェットで、水平(行、Row)方向と垂直(列、Column)方向で柔軟なレイアウトが作成できる。

Stack

ペイント順にウィジェットを互いの上に配置できる。子ウィジェットに対してPositionedウィジェットを使ってStackの上段、右段、下段または左段を基準にして配置できる。

Container

長方形の視覚要素を作成できるウィジェットで、BoxDecorationで背景、境界線、影など、飾ることができる。マージン、パディング、制約を持つことができ、マトリックスを使って3次元空間で絵変形できる。

上の基本ウィジェットを使ったサンプルコードを見てみよう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      title: 'My App',
      home: SafeArea(
        child: MyScaffold(),
      ),
    ),
  );
}

class MyAppBar extends StatelessWidget {
  const MyAppBar({required this.title, super.key});

  final Widget title;

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 56,
      padding: const EdgeInsets.symmetric(horizontal: 8),
      decoration: BoxDecoration(color: Colors.blue[500]),
      child: Row(
        children: [
          const IconButton(
            onPressed: null,
            icon: Icon(Icons.menu),
            tooltip: 'Navigation menu',
          ),
          Expanded(
            child: title,
          ),
          const IconButton(
            onPressed: null,
            icon: Icon(Icons.search),
            tooltip: 'Search',
          ),
        ],
      ),
    );
  }
}

class MyScaffold extends StatelessWidget {
  const MyScaffold({super.key});

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Column(
        children: [
          MyAppBar(
            title: Text(
              'Example title',
              style: Theme.of(context).primaryTextTheme.titleLarge,
            ),
          ),
          const Expanded(
            child: Center(
              child: Text('Hello, world!'),
            ),
          ),
        ],
      ),
    );
  }
}

iOS Simulator

多くのマテリアル・デザイン・ウィジェットは、テーマデータを継承し、適切に表示するために、MaterialApp内に存在する必要がある。

マテリアル・デザイン?

Googleが推奨するデザイン手法のガイドライン。ユーザーの操作性を重視して、感覚で理解できることを目的としている。

MyAppBarから見てみよう。実行画面の上の青いバーのところだ。

コードから高さは56ピクセルで固定長さ、パディングはhorizontal指定なので左右で8ピクセル固定、背景色は青で指定している。

子ウィジェットとしてRowを使って1行内で3つのウィジェットを表示している。Rowの中に3つあり、左から並ぶことになるが、titleをExpandedの中に入れているのでtitleが拡張し、アイコンが両端に表示されるようになった。Expandedがなかったら、左からくっついて表示される。

MyScaffoldを見てみよう。MyAppBarとテキスト表示の2つが縦で並ぶようにColumnを使っている。Expandedを使っているのでMyAppBarの高さ56ピクセル以外はExpandedが拡張して使うことになる。

Expandedの中にCenterウィジェットで表示しているので画面(Expandedウィジェット)の真ん中にTextを表示することになる。

下のコードは上のサンプルをもうちょっと簡単に実現したものだ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      title: 'Flutter Tutorial',
      home: TutorialHome(),
    ),
  );
}

class TutorialHome extends StatelessWidget {
  const TutorialHome({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: const IconButton(
          icon: Icon(Icons.menu),
          tooltip: 'Navigation menu',
          onPressed: null,
        ),
        title: const Text('Example Title'),
        actions: const [
          IconButton(
            icon: Icon(Icons.search),
            tooltip: 'Search',
            onPressed: null,
          ),
        ],
      ),
      body: const Center(
        child: Text('Hello, world!'),
      ),
      floatingActionButton: const FloatingActionButton(
        tooltip: 'Add',
        onPressed: null,
        child: Icon(Icons.add),
      ),
    );
  }
}

iOS Simulator

Scaffoldウィジェットは足場のようにウィジェットを組み合わせすることができる。自前で作ったMyAppBarをAppBarウィジェットを使って表現している。bodyに文字列、最後に+ボタンを追加している。

Flutterには大きく二つのデザインに分かれていてその一つがマテリアル・デザインだ。もう一つはCupertinoだが、これはiOS中心のデザインに従っているものでiOSネイティブではないがデザインを従っているものである。Cupertinoを使うにはCupertinoパッケージが必要だ。

コメントする