最低限知っておきたい実装方法
Flutterを使ってモバイルをアプリを実装するうえで、「最低限これだけは知っておきたい実装」を網羅しておく。
「ここの内容を組み合わせれば、どんなものでも作れる」というレベルになるまでブラッシュアップしていきたい。
ルーティング
今回記載しているのは、いわゆる「名前付きルート」という実装方法。
MaterialAppのプロパティであるroutesに、名称と実際に表示したいウィジェットを定義する。
以下の場合、「/top」という名称を指定したときに「TopPageウィジェット」を表示する。
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
initialRoute: '/',
routes: <String, WidgetBuilder>{
'/': (BuildContext context) =>
MyHomePage(title: 'Flutter Demo Home Page'),
'/top': (BuildContext context) => TopPage()
},
);
}
ページ遷移
ページ遷移の処理は、スタックによるpushとpopをイメージする。
次のページに遷移するときは、pushNamedで名称を指定して遷移。
前のページに戻るときは、popで戻る。
// 「/top」を指定してページ遷移
Navigator.of(context).pushNamed('/top',
arguments: new MyPageArguments(
name: this._name!,
mailAddress: this._mailAddress!));
// 前のページに戻る
Navigator.of(context).pop();
ページ遷移する際に、次のページに引数として値を渡すことができる。
今回の例の場合は複数の値(name, mailAddress)を渡すため、
MyPageArgumentsクラスを定義して受け渡しに利用している。
class MyPageArguments {
final String name;
final String mailAddress;
MyPageArguments({required this.name, required this.mailAddress});
}
// 引数を受け取る
final MyPageArguments args = ModalRoute.of(context)!.settings.arguments as MyPageArguments;
String _name = args.name
入力フォーム
Formクラスを利用する。
Formクラスは、TextFieldなどをグループ化してくれる。
ポイントは後ほど解説。
final _form = GlobalKey<FormState>();
String? _name;
String? _mailAddress;
String? _password;
Form(
key: _form,
child: Column(
children: <Widget>[
new TextFormField(
enabled: true,
maxLength: 10,
style: TextStyle(color: Colors.red),
obscureText: false,
validator: (value) {
if (value!.isEmpty) {
return 'Please provide a value.';
}
return null;
},
onSaved: (String? value) {
_userId = value;
},
),
new TextFormField(
enabled: true,
style: TextStyle(color: Colors.red),
obscureText: false,
validator: (value) {
if (value!.isEmpty) {
return 'Please provide a value.';
}
return null;
},
onSaved: (String? value) {
_mailAddress = value;
},
),
new TextFormField(
enabled: true,
maxLength: 10,
style: TextStyle(color: Colors.black),
obscureText: true,
maxLines: 1,
onSaved: (String? value) {
_password = value;
}),
ElevatedButton(
child: const Text('Button'),
style: ElevatedButton.styleFrom(
primary: Colors.orange,
onPrimary: Colors.white,
),
onPressed: () {
if (_form.currentState!.validate()) {
_form.currentState!.save();
Navigator.of(context).pushNamed('/top',
arguments: new MyPageArguments(
name: this._name!,
mailAddress: this._mailAddress!));
}
},
),
],
)
)
バリデーション
バリデーションは、各TextFormFieldのvalidatorプロパティに定義する。
autovalidateModeにonUserInteractionを指定することで、ユーザ入力時にリアルタイムにバリデーションチェックを行う。
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if (value!.isEmpty) {
return 'Please provide a value.';
}
return null;
},
以下のように、バリデーションエラーがない場合に次のページに遷移させる。
if (_form.currentState!.validate()) {
_form.currentState!.save();
Navigator.of(context).pushNamed('/top',
arguments: new MyPageArguments(
name: this._name!,
mailAddress: this._mailAddress!));
}
Formの内容を保存
FormStateインスタンスが持つsaveメソッドにより、入力されたFormの内容を保存する。
保存時に各TextFormFieldのonSavedが実行されるため、この中でプライベート変数に値を設定している。
// 保存
_form.currentState!.save();
// onSavedが呼び出される
onSaved: (String? value) {
_userId = value;
},
今後追記する予定の内容
- StatefulWidgetのライフサイクル