【 Flutter 】Flutter を 基礎 から 学習 ( スタートガイド編 ) part22 画面遷移 Named Routes
「基礎 から 学ぶ Flutter 」という書籍で 学習 したことを ブログでアウトプットしていこうと思います。今回は スタートガイド編 ( part22 )です。
前回
【 Flutter 】Flutter を 基礎 から 学習 ( スタートガイド編 ) part21 画面遷移 Named Routes
Named Routesの続きになります。
画面遷移
Named Routes
Named Routesの基本実装は以下のようになります。
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), // home: MyHomePage(title: 'Flutter Demo Home Page'), initialRoute: '/', routes: { '/': (context) => FirstPage(), '/second': (context) => SecondPage(), }); } } class FirstPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('First Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.pushNamed(context, '/second'); }, child: Text('Next Page'), ), ), ); } } class SecondPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Secnd Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.pop(context); }, child: Text('Go back'), ), ), ); } }
動作は今までの実装と変わりませんね。
値の渡し方は2つの方法があります。
- pushNmaed()の引数argumentsプロパティに設定する
- このとき、ModalRouteクラスを使用し受け取る
- 本書では
var messageFromFirst = ModalRoute.of(context).settings.arguments;
と記載されているが、以下のエラーが発生。Error: Property 'settings' cannot be accessed on 'ModalRoute<Object?>?' because it is potentially null. - 'ModalRoute' is from 'package:flutter/src/widgets/routes.dart' ('/D:/flutter/packages/flutter/lib/src/widgets/routes.dart'). - 'Object' is from 'dart:core'. Try accessing using ?. instead. var messageFromFirst = ModalRoute.of(context).settings.arguments; ^^^^^^^^/* Your code... */
var messageFromFirst = ModalRoute.of(context)?.settings.arguments;
とした。 -
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), // home: MyHomePage(title: 'Flutter Demo Home Page'), initialRoute: '/', routes: { '/': (context) => FirstPage(), '/second': (context) => SecondPage(), }); } } class FirstPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('First Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.pushNamed(context, '/second', arguments: 'messageFromFirst'); // ★ここです。 }, child: Text('Next Page'), ), ), ); } } class SecondPage extends StatelessWidget { Widget build(BuildContext context) { var messageFromFirst = ModalRoute.of(context)?.settings.arguments; print(messageFromFirst); return Scaffold( appBar: AppBar(title: const Text('Second Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.pop(context); }, child: Text('Go back'), ), ), ); } }
実行してみました。
※コンソールに出力する実装なので画面遷移自体は特に変化ありません。
- routesプロパティと同列に、
onGenerateRoute
プロパティを定義- コンストラクタで渡す方法らしいです。本書ではコンストラクタ定義まで記載がないので流れのまま実装したのでは動作しない。
※動的にSecondPageにコンストラクタを定義しているのかと思いましたよ(笑
「画面間のデータ受け渡し」の説のSecondPageの実装を参考にしましょう。
さらに、settings.arguments
の戻り値の方はObject?
らしいのでSecondPageのコンストラクタで受ける際は注意が必要です。 -
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), // home: MyHomePage(title: 'Flutter Demo Home Page'), initialRoute: '/', routes: { '/': (context) => FirstPage(), //'/second': (context) => SecondPage(), }, onGenerateRoute: (settings) { if (settings.name == '/second') { var messageFromFirst = settings.arguments; return MaterialPageRoute( builder: (context) { return SecondPage(messageFromFirst); }, ); } return null; }, ); } } class FirstPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('First Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.pushNamed(context, '/second', arguments: 'messageFromFirst'); }, child: Text('Next Page'), ), ), ); } } class SecondPage extends StatelessWidget { final Object? messageFromFirst; SecondPage(this.messageFromFirst); Widget build(BuildContext context) { // var messageFromFirst = ModalRoute.of(context)?.settings.arguments; print(this.messageFromFirst); return Scaffold( appBar: AppBar(title: const Text('Second Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.pop(context); }, child: Text('Go back'), ), ), ); } }
- 実行した結果
- コンストラクタで渡す方法らしいです。本書ではコンストラクタ定義まで記載がないので流れのまま実装したのでは動作しない。
最後に
ソースコードが断片的なのでなかなか難しいですね😅
今日はここまで!
ディスカッション
コメント一覧
まだ、コメントがありません