2022/9/22/Flutter/popUntil and WillPopScope

 

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home page')),
      body: Center(
        child: ElevatedButton(
          child: Text('Go to Second page'),
          onPressed: () {
            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (context) => SecondPage(),
              ),
            );
          },
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second page')),
      body: Center(
        child: ElevatedButton(
          child: Text('Go to Third page'),
          onPressed: () {
            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (context) => ThirdPage(),
              ),
            );
          },
        ),
      ),
    );
  }
}

class ThirdPage extends StatelessWidget {
  const ThirdPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Third page'),

      ),
      body: Center(
        child: Column(
          children: [
            Text('Third page'),
            //Spacer(flex: 2,),
            SizedBox(height:50.0,),
            ElevatedButton(
              child:Text('Go to Home Page'),
              onPressed:(){
                int numOfPop = 0;
                //コールバックがtrueを返すまで、繰り返し「コールバック+pop」が呼び出される。
                Navigator.of(context).popUntil((_) => numOfPop++ >= 2);
              },
            ),
          ],
        ),
      ),
    );
  }
}

 

Navigator.of(context).popUntilを使うと、一度に複数画面popする(戻る)ことができます。

Navigator.of(context).popUntil allows you to pop (back) multiple screens at once.

 

ソースコードを見るとわかりますが、引数として渡したコールバックがtrueを返すまで「コールバック呼び出し+pop」を繰り返す、という実装です。

Looking at the source code, it seems that “callback call + pop” is repeated until the callback passed as an argument returns true.

 

ということで、上記のサンプルコードでThirdPageのボタンを押すと二回popされてHomePageまで遷移します。

So, when you press the ThirdPage button in the above sample code, it will be popped twice and transition to HomePage.

(_) => numOfPop++ >= 2

上記のnumOfPop++が後置インクリメントなので「評価してから加算する」ということなんですね。なので

0 → 1

の2回popが行われる、ということですね。

Since the above numOfPop++ is a post-increment, it means “evaluate and then add”.

So,

 0 → 1

It means that pop is performed twice.

 

ですので引数として渡すコールバックを下記のように変えるとSecondPageへ遷移する挙動に変わりますね、はい。

So if you change the callback passed as an argument as follows, the behavior will change to transition to SecondPage, year.

(_) => ++numOfPop >= 2

 


さらに、WillPopScopeウィジェットを使うと、AppBarの戻るボタンの挙動を上書きできます。

Additionally, the WillPopScope widget allows you to override the behavior of the AppBar’s back button.

class ThirdPage extends StatelessWidget {
  const ThirdPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop:() async {
        int numOfPop = 0;
        //コールバックがtrueを返すまで、繰り返し「コールバック+pop」が呼び出される。
        Navigator.of(context).popUntil((_) => numOfPop++ >= 2);
        return true;
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text('Third page'),
        ),
        body: Center(
          child: Column(
            children: [
              Text('Third page'),
              //Spacer(flex: 2,),
              SizedBox(height:50.0,),
              ElevatedButton(
                child:Text('Go to Home Page'),
                onPressed:(){
                  int numOfPop = 0;
                  //コールバックがtrueを返すまで、繰り返し「コールバック+pop」が呼び出される。
                  Navigator.of(context).popUntil((_) => numOfPop++ >= 2);
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

ThirdPageを上記のように変更すると、ThirdPageのAppBarの戻るボタンを押した時にもHomePageに遷移する挙動になります。

If you change ThirdPage as above, it will transition to HomePage even when you press the back button of AppBar of ThirdPage.


今回は以上です。

That’s all for today.

 

今プロでは今プロユーザーの皆様のFlutter/Dartの学習をサポートするため現在無料で質問を受け付けております。

We are currently accepting questions for free to support the learning of Flutter/Dart for all users of our service.

 

サポートできる範囲でお役に立ちたいと思っております。サポートできる範囲を超えた質問はサポートできません。

We would like to help you as much as we can. Questions beyond the scope of support cannot be supported.

 

お気軽に質問・要望などお寄せください。

Please feel free to send us your questions and requests.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です