(↑は「Run」ボタン押してしばらく待つと、動かせます)

ざっくり概要整理

  • Googleが作ったクロスプラットフォームなアプリ開発フレームワーク。
    • Android、IOS、Win、Mac、Linux、Web、Fuchsiaが対象。
    • 2018/12/4 1.0リリース > 2021/3/3 2.0リリース > 2022/1 現在、v2.8
  • 言語はDart
    • 元はGoogleがJavaScriptの代替を目指して作られた言語。(現在は一旦断念)
    • WebのためにJavaScriptに、Android、IOSのためにネイティブコードにコンパイルできる。
    • DartVMにてスタンドアローンで実行できる。
    • オブジェクト指向、関数型、命令型のマルチパラダイム。v2.x系は強い静的型付け。
    • プリミティブもnullも関数も全てオブジェクト。
    • ジェネリック、ミックスイン、演算子オーバーロード、ジェネレータ
    • 単一スレッド。アイソレートで並行処理。

環境構築

開発はVSCodeまたはAndroidStudioにプラグインいれてやるのが普通ぽい。

  1. ココからzipダウンロードして解凍、好きな場所においてbinフォルダにパス通す。
  2. ココからAndroidStadioダウンロードしてインストール。AVDマネージャー起動してエミュレータ作る。
  3. AndroidStudio(またはVSCode)にFlutterとDartのプラグイン入れる。
  4. AndroidStudioの Settings > Languages & Frameworks にFlutterとDartのパス設定。
  5. コマンドラインから flutter doctor と入力。パス設定しろ、ライセンス許諾しろ等、怒られる。
  6. flutter config --android-studio-dir="AndroidStudioのパス"
  7. flutter doctor --android-licenses でy押してライセンス同意。
  8. flutter doctor が全部OKになるまで付き合う
  9. AndroidStudioで new Flutter Project にてプロジェクト作成すると、カウンターアプリのサンプル付プロジェクトができる。



環境作るの面倒な場合、とりあえずWebで書いて動かせる DartPad で試すのもアリ。
記事の最初に設置した画面はDartPad。(内容はサンプルのカウンターアプリ)



DartPadは GitHub Gist に置いたコードを読み込んで、ブログに埋め込みも可能。

<iframe style="width:900px;height:500px;" src="https://dartpad.dev/embed-flutter.html?id=(GistのID)&split=80&theme=dark"></iframe>

コード読んでみる

まずはサンプル出力されたコードを解析してみる。
とりあえず先頭から。

import 'package:flutter/material.dart';

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

importはマテリアルデザインのテーマ読み込み。
ios風が良い場合、package:flutter/cupertino.dart てのもある模様。

main関数がエントリポイント。runAppで自分のWidgetを起動。



余計なコメントを除去。処理の中身も一旦ゴッソリ消して、クラスのガワだけにしたらこんな感じ。

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
}

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

class _MyHomePageState extends State<MyHomePage> {
}

classが3つある。


それぞれを見る前に、まずこの行でDartの勉強↓

const MyApp({Key? key}) : super(key: key);


これはコンストラクタ。

  • constが付いているが、これは@immutableアノテーションが付いたクラスのコンストラクタに必要。
    ここでは上位のWidgetクラスにアノテーションが付いている。普通は要らない。
  • 引数Key?は、nullable(Null許容型)。
  • Keys? を囲う{}は、名前付き引数(Named Parameter)。このように{}で囲うと、呼び出し側がMyApp(key: 'hoge')のように、名前つき引数で呼び出すことを強制できる。
  • c++ のコンストラクタ初期化リストのように:の後に初期化が書ける。ここでは上位コンストラクタを呼び出している。

さてFlutterに戻る。

各クラスはそれぞれ、以下を拡張している。

クラス名 extends 拡張クラス
MyApp StatelessWidget
MyHomePage StatefulWidget
_MyHomePageState State
  • Flutterでは、UI要素は全てWidget
  • 更新不要な要素はStatelessWidget、動的に更新が必要な要素はStatefulWidgetを継承するように設計する。
    • この画面はカウンターということで、ボタン押下でカウントアップする部分は動的更新が必要なのでStatefulWidgetを、ヘッダー等の更新不要な部分はStatelessWidgetを、のように使い分けている。
  • StatefulWidgetには、その更新用にStateを継承したクラスを用意する。

_MyHomePageState_(アンダースコア)が付いているが、これはDartでプライベートを表す場合に付ける。
ただし、同一モジュール内ではアクセス出来てしまう。Dartにおけるカプセル化はライブラリ単位、という考え方。



長くなってきたので次回へ。

次はそれぞれのクラスの中を見ていきます。