Flutterに入門してみる (その1)
(↑は「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にプラグインいれてやるのが普通ぽい。
- ココからzipダウンロードして解凍、好きな場所においてbinフォルダにパス通す。
- ココからAndroidStadioダウンロードしてインストール。AVDマネージャー起動してエミュレータ作る。
- AndroidStudio(またはVSCode)にFlutterとDartのプラグイン入れる。
- AndroidStudioの
Settings > Languages & Frameworks
にFlutterとDartのパス設定。 - コマンドラインから
flutter doctor
と入力。パス設定しろ、ライセンス許諾しろ等、怒られる。 flutter config --android-studio-dir="AndroidStudioのパス"
flutter doctor --android-licenses
でy押してライセンス同意。flutter doctor
が全部OKになるまで付き合う- 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におけるカプセル化はライブラリ単位、という考え方。
長くなってきたので次回へ。