🐥

Flutter の始め方メモとサンプルアプリのコメント部分翻訳

2020/10/23に公開

私の環境は Mac OS Catalina(10.15.7) + Visual Studio Code(以下VSCode) です。

Flutter の始め方

既にいろんなところで解説されているのでリンクを。
公式読むだけでも十分わかりやすいです。

基本的にはflutterのバイナリをダウンロードしてきてパスを通したら
flutter doctor して表示される指示に従っていけばOK。

サンプルアプリ解説

サンプルアプリのコードが何をしているかの解説は以下に詳しく解説されてありました。
合わせてみてみてください。

サンプルアプリ翻訳

任意のディレクトリでアプリを新規作成して起動できます。
ターミナルから実施するなら以下。

% flutter create myapp
% cd myapp
% open -a Simulator
% flutter run

作成された myapp フォルダを VSCode で開き、
./lib/main.dart を開く。
以下は開いたファイル。英語コメントが入っているところを翻訳してみました。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // この widget が application のルートです。
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // ここがアプリケーションのテーマです。
        // "flutter run" でアプリケーションを実行してみてください。
        // 表示されたアプリケーションには青いツールバーがあります。 次に、アプリを終了せずに、
        // 以下のprimarySwatchをColors.greenに変更してから、
        // 「ホットリロード」します。
        // ("flutter run" を実行したコンソールで "r" を押します。
        //   または、IDEで「ホットリロード」に変更するだけです)
        // カウンターがゼロにリセットされなかったことに注意してください。 アプリケーション
        // 再起動されません。
        primarySwatch: Colors.blue,
        // VisualDensity により視覚的な詰まり具合(密度)を調整します。
        // デスクトッププラットフォームの場合はコントロールが小さくなり、
        // モバイルプラットフォームより密度が高くなります。、
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // このMyHomePageウィジェットは、アプリケーションのホームページです。
  // ステートフル、つまり影響を与えるフィールドを含む State object(以下に定義)が
  // どのように見えるかに影響します。

  // このクラスは、State の構成です。
  // これは親(今回は App widget)によって提供された値 (今回は title) を保持し、
  // State の build method で使用されます。
  // Widget の subclass のフィールドは常に定数宣言 "final" です。

  final String title;

  
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // この setState関数は Flutterフレームワークに State の変更を伝えます。それにより、
      // 以下の build関数が再実行され、表示に更新された値を反映するようになっています。
      // setState関数を呼び出さずに _counter の値を変更すると、
      // build関数が再実行されないため、変更が何も反映されないことが起こります。
      _counter++;
    });
  }

  
  Widget build(BuildContext context) {
    // この build関数はsetState関数が呼び出されるたびに再実行されます。
    // 例えば、今回は上記 _incrementCounter関数 によって再実行されています。
    //
    // Flutterフレームワークは、ビルドメソッドの再実行を高速化するように
    // 最適化されているため、widget のインスタンスを個別に変更する必要はなく、
    // 更新が必要なものをすべて再構築できます。
    return Scaffold(
      appBar: AppBar(
        // ここでは、App.build関数によって作成された
        // MyHomePageオブジェクトから値を取得し、
        // それを使用してアプリバーのタイトルを設定します。
        title: Text(widget.title),
      ),
      body: Center(
        // センターはレイアウトウィジェットです。
        // それは1つのchildを持ち、それを親の真ん中に配置します。
        child: Column(
          // Column もレイアウトウィジェットです。
          // それは子のリストを垂直に配置します。 デフォルトでは、子を水平方向に合わせて
          // サイズを調整し、親と同じ高さにしようとします。
          //
          // 配置を確認するには "debug painting" を呼び出すことで
          // 各ウィジェットのワイヤーフレームを見てみることが出来ます。
          // ("flutter run" を実行したコンソールで "p" を押す、
          //  または AndroidStudioのFlutterInspectorから
          // 「ToggleDebugPaint」アクションを選択するか、
          //  Visual Studio Codeの「ToggleDebugPaint」コマンドを選択します)
          //
          // Column には、それ自体のサイズと子の配置方法を制御するための
          // さまざまなプロパティがあります。 ここでは、mainAxisAlignmentを使用して、
          // 子を垂直方向の中央に配置します。 列が垂直であるため、
          // ここでの主軸は垂直軸です(交差軸は水平になります)。
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // この末尾のコンマにより、ビルドメソッドの自動フォーマットがより適切になります。
    );
  }
}

特に難しいことは書かれていないですね。要約すると以下のような感じでしょうか。

  • runApp(MyApp()); とあるように MyApp Class がアプリケーションのルート
  • MyApp Class の戻り値で指定している MaterialApp で大まかなテーマを決めている
  • flutter run したコンソールで r することでホットリロードができる
  • StatefulWidget を継承した MyHomePage Class でStatefulページを定義
  • 管理するStateは createState を override して指定
  • setState() を使って State を更新することで build() が再実行され画面に反映される
  • CenterColumn といったレイアウトウィジェットを使うことで配置を定義できる
  • flutter run したコンソールで p することで配置のワイヤーフレームを確認できる

また、./pubspec.yaml にパッケージ情報が書かれています。
こちらもコメントを翻訳しました。

name: sample_app
description: A new Flutter project.

# publish_to: 'none' は `pub publish` を使ってパッケージが誤ってpub.devに公開されるのを防ぎます。
# これはプライベートパッケージに適しています。
publish_to: 'none' # pub.devに公開する場合は、この行を削除してください

# version: 1.0.0+1 はアプリケーションのバージョンとビルド番号を定義します。
# バージョン番号は、1.2.43のようにドットで区切られた3つの番号と、
# それに続く+で区切られたオプションのビルド番号です。
# 
# version と builder number の両方がフラッターでオーバーライドされる可能性があります。
# それぞれ --build-name と --build-number を指定してビルドします。
# 
# Androidでは、build-name は versionName として使用され、
# build-number は versionCode として使用されます。
# Android のバージョニングについて詳しくは以下を参照してください。
# https://developer.android.com/studio/publish/versioning
# 
# iOSでは、build-name は CFBundleShortVersionString として使用され、
# build-number は CFBundleVersion として使用されます。
# iOS のバージョニングについて詳しくは以下を参照してください。
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1

environment:
  sdk: ">=2.7.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter


  # 以下は、CupertinoIconsフォントをアプリケーションに追加します。
  # iOSスタイルのアイコンのCupertinoIconsクラスで使用します。
  cupertino_icons: ^1.0.0

dev_dependencies:
  flutter_test:
    sdk: flutter

# この pubspec.yaml ファイルのDart部分の一般的な情報については以下を参照してください。
# https://dart.dev/tools/pub/pubspec

# 次のセクションは Flutter 固有の部分です。
flutter:

  # 次の行は、Material Icons font がアプリケーションに含まれていることを指定し、
  # material Icons class のアイコンを使用できるようにします。
  uses-material-design: true

  # アプリケーションにアセットを追加するには、次のように assets セクションを追加します:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # 画像アセットは、1つ以上の解像度固有の "variants" を参照できます。
  # 詳しくは以下を参照してください。
  # https://flutter.dev/assets-and-images/#resolution-aware.

  # パッケージの依存関係からアセットを追加する方法の詳細は
  # 以下を参照してください。
  # https://flutter.dev/assets-and-images/#from-packages

  # アプリケーションにカスタムフォントを追加するには、
  # この "flutter" セクションに fonts セクションを追加します。
  # このリストの各エントリには、フォントファミリ名を含む "family" キーと、
  # フォントのアセットおよびその他の記述子を示すリストを含む "fonts" キーが必要です。
  # 以下、例:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # パッケージの依存関係からの "fonts" に関する詳細については、以下を参照してください。
  # see https://flutter.dev/custom-fonts/#from-packages

翻訳は以上です。


コメントを取り除くとコードはかなりシンプル

./lib/main.dart の全てのコメントを取り除いたのがこちら。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

たったこれだけのコードでアプリの起動からUIの配置まで完了してしまうのは素晴らしいですね。
また、Android Studio の Flutter plugin や VSCode の Flutter 拡張機能もよく出来ており、
下図のようにともすれば読み解くのが難解になってしまいがちな関数型の記述の閉じかっこの部分に
対応する関数宣言をコメントのように表示してくれます。
(=灰色 // はコメント記述ではなく拡張機能での自動表示です)

Undefined.png

サンプルアプリではコード分割の指針などは提示されてないので、
全コードが1ファイルになってますね。この辺りの指針が見つかったらまた記事にします。

Discussion