Flutter WillPopScope用于嵌套导航 [英] Flutter WillPopScope for nested Navigation

查看:114
本文介绍了Flutter WillPopScope用于嵌套导航的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有带有嵌套导航器的Flutter应用,并且我想覆盖"onBackPressed"在我的嵌套屏幕中使用WillPopScope.

I have Flutter App with nested Navigator and I want to override "onBackPressed" using WillPopScope in my nested screen.

假设我有MainScreenPrimaryScreenSecondaryScreen. PrimaryScreen是嵌套的导航器,它具有多个屏幕,如PrimaryOneScreenPrimaryTwoScreenPrimaryThreeScreen.

Let's say I have MainScreen, PrimaryScreen, and SecondaryScreen. PrimaryScreen is nested Navigator, it have several screen like PrimaryOneScreen, PrimaryTwoScreen, and PrimaryThreeScreen.

SecondaryScreen也是嵌套导航器,就像PrimaryScreen一样,它具有3个屏幕.

SecondaryScreen is also a nested Navigator, just like PrimaryScreen, it have 3 screens.

以下是我要实现的目标的说明

Here the illustration of what i want to achieve

MainScreen-> PrimaryScreen(PrimaryOneScreen-> PrimaryTwoScreen-> PrimaryThreeScreen)

MainScreen -> PrimaryScreen(PrimaryOneScreen -> PrimaryTwoScreen -> PrimaryThreeScreen)

当我在PrimaryTwoScreen上的职位时,我想使用覆盖"onBackPressed"的位置回到PrimaryOneScreen.使用WillPopScope小部件.但是onWillPop当我按下后退"按钮时从未调用,并且屏幕直接返回到MainScreen.

When my position on PrimaryTwoScreen, I want to get back to PrimaryOneScreen with overriding "onBackPressed" using WillPopScope Widget. But onWillPop never called when I press back button, and my screen go back directly to MainScreen.

这是我的密码

MainScreen.dart

MainScreen.dart

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MainApp(),
      onGenerateRoute: (settings){
        WidgetBuilder builder;
        switch(settings.name){
          case 'primary' :
            builder = (BuildContext _) => PrimaryScreen();
            break;
          case 'secondary' :
            builder = (BuildContext _) => SecondaryScreen();
            break;
          case 'main' :
            builder = (BuildContext _) => MainApp();
            break;
          default :
            throw Exception('Invalid route: ${settings.name}');
        }

        return MaterialPageRoute(
            builder: builder,
            settings: settings
        );
      },
    );
  }
}


class MainApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: <Widget>[
          FlatButton(
            onPressed: (){
              Navigator.pushNamed(context, 'primary');
            },
            child: Text('To Page Primary'),
          ),
          FlatButton(
            onPressed: (){
              Navigator.pushNamed(context, 'secondary');
            },
            child: Text('To Page Secondary'),
          )
        ],
      ),
    );
  }

}

PrimaryScreen.dart

PrimaryScreen.dart

class PrimaryScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Navigator(
        initialRoute: 'primary/pageone',
        onGenerateRoute: (RouteSettings settings){
          WidgetBuilder builder;
          switch(settings.name){
            case 'primary/pageone' :
              builder = (BuildContext _) => PrimaryOneScreen();
              break;
            case 'primary/pagetwo' :
              builder = (BuildContext _) => PrimaryTwoScreen();
              break;
            case 'primary/pagethree' :
              builder = (BuildContext _) => PrimaryThreeScreen();
              break;
            default :
              throw Exception('Invalid route: ${settings.name}');
          }

          return MaterialPageRoute(
              builder: builder,
              settings: settings
          );
        },
      );
  }

}

PrimaryOneScreen.dart

PrimaryOneScreen.dart

class PrimaryOneScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Primary Page'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
           FlatButton(
              onPressed: (){
                Navigator.pushNamed(context, 'primary/pagetwo');
              },
              child: Text('To Page Two'),
            ),
            FlatButton(
              onPressed: (){
                Navigator.pushNamed(context, 'primary/pagethree');
              },
              child: Text('To Page Three'),
            ),
          ],
        ),
      ),
    );
  }

}

PrimaryTwoScreen.dart

PrimaryTwoScreen.dart

class PrimaryTwoScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: ()async{
        print('willPopScope');
        Navigator.of(context, rootNavigator: false).pop();
        return true;
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text('Secondary Page'),
        ),
        body: Center(
          child: Column(
            children: <Widget>[
              FlatButton(
                onPressed: (){
                  Navigator.pushNamed(context, 'primary/pageone');
                },
                child: Text('To Page One'),
              ),
              FlatButton(
                onPressed: (){
                  Navigator.pushNamed(context, 'primary/pagethree');
                },
                child: Text('To Page Three'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

PrimaryThreeScreen.dart

PrimaryThreeScreen.dart

class PrimaryThreeScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Primary Page'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            FlatButton(
              onPressed: (){
                Navigator.pushNamed(context, 'primary/pageone');
              },
              child: Text('To Page One'),
            ),
            FlatButton(
              onPressed: (){
                Navigator.pushNamed(context, 'primary/pagetwo');
              },
              child: Text('To Page Two'),
            )
          ],
        ),
      ),
    );
  }

}

编辑 我添加了一张图像来说明我想要实现的目标.

EDIT I added an image to illustrate what I want to achieve.

如何仅在嵌套导航器上弹出?

How to pop only on nested navigator?

谢谢!

推荐答案

尝试使用此链接 https://medium.com/flutter-community/flutter-push-pop-push-1bb718b13c31

检查用例:pushReplacementNamed 标记说明

这篇关于Flutter WillPopScope用于嵌套导航的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆