Flutterについて基本的なところのまとめ
自分用のメモ
(参考)Flutter by Example
(参考)DroidKaigi2018で発表したFlutterアプリの話のスライド補足
Dart全般
- Javaのようにクラスをインスタンス化してメソッドを呼び出さなくてもいい
- オーバーライドメソッドはどのタイミングで呼ばれるか不明
Widgetについて
- Widgetはreactにもある概念
- newされて利用される(2018年時点ではnewを省略するのが主流らしい)
- Widgetクラスは必ず他のWidgetを返すbuildメソッドをもつ
- buildメソッドはWidgetの代わりにテキストを返すこともできる
- Widgetの入れ子でflutterは構成される
- 表示もアクションもバックグラウンドもCSSもWidgetの入れ子で表現する
StatelessWidget
- StatelessWidgetを継承した1つのクラスで構成されている
- StatelessWidgetはbuildメソッドを持ち、Widgetもしくはテキストを返す
- 返すWidgetはStatefulWidget(MaterialAppとか)でもOK
- 「state(状態)」の概念がないため、動的に変化しないWidget
StatefulWidget
- Widgetにstateの概念をいれて拡張したもの
- stateが変化したときに再描画を指示するメソッドが組み込まれている
- StateクラスとWidgetクラスの2つのクラスで構成されている
- StatefulWidgetはbuildメソッドを持たず、createStateメソッドを持ち、これがStateクラスを返す
- StatefulWidget自体はシンプルな構造で複雑な処理等はStateクラスで持つ
- Stateクラスで機能的なメソッドを実装する
- Stateクラスはbuildメソッドをもち、Widgetを返すときに定義したメソッドを
アクションとして組み込める - returnできるWidgetはいくつも種類があり、TextやImage、TextInput、Scaffold等
- ScaffoldはルートページとなるデザインWidgetで基本的なレイアウト構造
StatefulWidgetのメソッド構成
Widgetクラス
createState()
ビルド後に呼ばれるメソッドで必須
型はState
Stateクラス
initState()
最初に一度呼ばれる
Widgetツリーの初期化を実行
didChangeDependencies()
initState()呼び出し直後に呼ばれる
Widgetツリーの変更を要素に通知する
build()
didChangeDependencies()呼出し後にしか呼ばれない
複数回呼ばれる
Widgetツリーを置き換える
didUpdateWidget(Widget oldWidget)
リビルド時のinitState()的な位置づけ
setState()
任意で呼べるメソッド
Widgetツリーを再構成して、変更を反映させる
簡単な変数の代入だけでなく非同期処理でも使える
deactivate()
StateをWidgetツリーから削除する
滅多に使わないらしい
dispose()
Stateを永続的に削除する
画面をおとすときやストリーム停止で使うらしい
サンプルソース
main.dart
// メイン関数、実行時に最初に呼ばれる
// runAppメソッドは引数のwidgetをスクリーンにアタッチする
// runAppメソッドの引数のWidgetが画面いっぱいに表示される
void main() => runApp(new MyApp());
// runAppの引数として生成され、最初にインスタンス化されるクラス
class MyApp extends StatelessWidget {
// このメソッドでリターンしたWidgetがメイン画面になる
@override
Widget build(BuildContext context) {
// MaterialAppで画面のテーマ等を設定できる
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.red,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
// MaterialAppにセットされるホーム画面
class MyHomePage extends StatefulWidget {
// コンストラクト
MyHomePage({Key key, this.title}) : super(key: key);
// 定数定義
final String title;
// アロー関数を用いて、Stateを呼ぶ
@override
_MyHomePageState createState() => new _MyHomePageState();
}
// Widgetから呼ばれるStateクラス
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
List<String> _data;
// メソッドの定義
void _incrementCounter() {
// 画面の再描画を実行する
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
// デザインWidget
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'You have pushed the button this many times:',
),
new Text(
_data.length.toString(),
),
new Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: new FloatingActionButton(
// 定義した再描画メソッドをボタン押下時のアクションにセット
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
1つのソースファイルで画面レイアウトからアクションまで記述できる
※画面右下のボタンをタップするたびに中央の数字がカウントアップされる