下記環境でFlutterアプリを開発中です。
ツールなど | バージョンなど |
---|---|
MacBook Air Early2015 | macOS Mojave 10.14.5 |
Android Studio | 3.6.1 |
Java | 1.8.0_131 |
Flutter | 1.12.13+hotfix.5 |
Dart | 2.7.0 |
リスト画面-詳細(編集画面)-戻って画面更新、という非常によくあるパターンで、Navigator.push
で起動した画面から、結果を戻す方法についての調査メモ。
戻るときの値セット
Navigator.pop
で戻る時に、値をセットする方法です。
Navigator.pop(context, 戻したい値/オブジェクト);
とするだけ。
受け取る方法
起動元で、結果を受け取る方法です。
1.通常
特に複雑なことをしないで、普通にNavigator.push
している場合です。
あるボタンでpush
している例です。
RaisedButton(
child: Text('Next'),
onPressed: () async {
final result = await Navigator.pushNamed(context, '/next');
debugPrint(result.toString); // 結果を処理
);
}
Navigator.push
を呼ぶ関数は、非同期処理としてasync
を付けます。
その中では、pushが戻ってくるのを待つという意味で、await Navigator.push
とします。
Navigator.push
が値を返してくれるので、それを受け取って処理をすれば良いです。
2.NavigationServiceを使っている場合
以下の記事で紹介した方法を使っている場合です。
Flutter/Navigator遷移にBuildContextを不要にする/遷移のWidgetTest
基本的にやることは同じですが、コードのサンプルとして残します。
class NavigationService {
final GlobalKey<NavigatorState> navigatorKey =
new GlobalKey<NavigatorState>();
Future<dynamic> navigateTo(String routeName, {Object args}) async {
return navigatorKey.currentState.pushNamed(routeName, arguments: args);
}
bool goBack() {
return navigatorKey.currentState.pop();
}
}
navigateTo
にasync
を付けます。
class MyViewModel with ChangeNotifier{
void navigateNextPage(final LogData data) async {
// ルート遷移
final NavigationService _navigationService = locator<NavigationService>();
final result =
await _navigationService.navigateTo('/next', args: data);
if (result) {
// trueなら更新があったのでウィジェットを再ビルドしなければならない
notifyListeners();
}
}
}
push
を呼んでいる関数をasync
にしています。
NavigationService#navigateTo
をawait
で待って、結果を受け取ってます。
このクラスはChangeNotifier
で、更新があったら再描画させたいためnotifyListeners
を呼んでいます。
これで、Flutter 画面遷移でデータを渡すと合わせると、Androidでいう
- Intentで次の画面にデータを投げる
- その画面でデータを書き換える
- 呼び出し元の画面にそのデータを返す
というのと同じことが出来るようになりました。
参考サイト
FlutterのNavigatorの使い方と仕組み
https://qiita.com/heavenosk/items/9e43298955a371221393