【 Flutter 】Flutter を 基礎 から 学習 ( スタートガイド編 ) part23 画面遷移 その他の遷移方法
「基礎 から 学ぶ Flutter 」という書籍で 学習 したことを ブログでアウトプットしていこうと思います。今回は スタートガイド編 ( part23 )です。
前回
【 Flutter 】Flutter を 基礎 から 学習 ( スタートガイド編 ) part22 画面遷移 Named Routes
今回はNavigator
クラスのそのほかの画面遷移について学習します。
画面遷移
maybePop
ルートのスタックが残り1つになるまでpopします。
「最初の画面に戻る」の場合に使用する想定でしょうかね?
最初の画面→2画面目→3画面目 の構成で、3画面目でmaybePopを使用してみました。
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(), '/third': (context) => ThirdPage(), }, ); } } 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('Second Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.pushNamed(context, '/third'); }, child: Text('Next Page'), ), ), ); } } class ThirdPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Third Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.maybePop(context); // ★ここに注目 }, child: Text('Go back'), ), ), ); } }
実行してみました。
最初の画面画面に戻ると思ったのですがそうではなかったですね・・・なんでしょうこれは・・・。
canPop
popできるかどうか確認するためのメソッドのようです。
popできない(つまりルート画面)の場合はfalse
となります。
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(), '/third': (context) => ThirdPage(), }, ); } } class FirstPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('First Page')), body: Center( child: ElevatedButton( onPressed: () { print('最初の画面でcanPop = ' + Navigator.canPop(context).toString()); Navigator.pushNamed(context, '/second'); }, child: Text('Next Page'), ), ), ); } } class SecondPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Second Page')), body: Center( child: ElevatedButton( onPressed: () { print('2画面目でcanPop = ' + Navigator.canPop(context).toString()); Navigator.pushNamed(context, '/third'); }, child: Text('Next Page'), ), ), ); } } class ThirdPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Third Page')), body: Center( child: ElevatedButton( onPressed: () { print('3画面目でcanPop = ' + Navigator.canPop(context).toString()); Navigator.maybePop(context); }, child: Text('Go back'), ), ), ); } }
実行して確認しました。
想定通りですね。
pushReplacement, pushReplacementNamed
First -> Second(ここでpushReplacement) -> Third の順で画面遷移した場合、
Thrird画面でpopするとFirst画面に遷移するということのようです。
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(), '/third': (context) => ThirdPage(), }, ); } } 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('Second Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.pushReplacementNamed(context, '/third'); // ★ここに注目 }, child: Text('Next Page'), ), ), ); } } class ThirdPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Third Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.pop(context); }, child: Text('Go back'), ), ), ); } }
実行してみると確かにThirdからいきなりFirstの画面に戻っているのがわかります。
popAndPushNamed
popAndPush
メソッドは無いのですね。
このメソッドが実装された画面Widget(ルート)を削除し、指定された画面Widgetをスタックの最後に挿入する。という認識でよいでしょうかね。
First -> Second-> Third(ここでpopAndPushNamed)
とすると、スタックはFirst -> Second-> (Third消滅)First
となります。
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(), '/third': (context) => ThirdPage(), }, ); } } 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('Second Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.pushNamed(context, '/third'); }, child: Text('Next Page'), ), ), ); } } class ThirdPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Third Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.popAndPushNamed(context, '/'); // ここに注目 }, child: Text('Go back'), ), ), ); } }
実行してみたところFirst(1回目) -> Second -> Third -> First(2回目)の順で画面が表示されました。
注目したいのはFirst画面に「戻る」アイコンが表示されていることです。
スタックされたFirst画面が表示されていることがわかります。
次にこのFirst画面の「戻る」アイコンをクリックするとSecond画面が表示されました。
Third画面がスタック上からなくなっているということですね。
最後に
文章にすると複雑(というか私の文章能力が無い)ですが動きを見ると感覚的に分かりますね。
今日はここまで!
ディスカッション
コメント一覧
まだ、コメントがありません