如何推送和弹出直到颤振中的特定路线

How to push and pop until to a specific route in flutter

我正在申请,在我的注销对话框中,我得到了这个代码。

  Navigator.of(context).pushAndRemoveUntil(
                    MaterialPageRoute(builder: (context) {
                  return AuthScreen();
                }), (route) {
                  // if( route is (MaterialPageRoute('/')))
                  // {

                  // }
                  // print(route);
                  return false;
                });


我只想推送 AuthScreen 并删除直到路由屏幕。怎么做?

所以在这段代码之后,堆栈包含根屏幕和 AuthScreen。

你可以这样做:

Navigator.pushAndRemoveUntil(
    context,   
    MaterialPageRoute(builder: (BuildContext context) => AuthScreen()), 
    ModalRoute.withName('/') // Replace this with your root screen's route name (usually '/')
);

您可以尝试的另一种方法是:

Navigator.pushAndRemoveUntil(
  context,
  MaterialPageRoute(builder: (BuildContext context) => AuthScreen()),
  (Route<dynamic> route) => route is RootPage (your root page's type)
);

还有一个:

Navigator.pushAndRemoveUntil(
  context,
  MaterialPageRoute(builder: (BuildContext context) => AuthScreen()),
  (Route<dynamic> route) => route.isFirst (pop until your first page)
);

示例应用程序:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:in_app_update/in_app_update.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: '/',
      routes: {
        '/': (context) => MyHome(),
      },
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Sample App'),
      ),
      body: Center(
        child: TextButton(
          onPressed: () => Navigator.push(
              context, MaterialPageRoute(builder: (context) => MyChild())),
          child: Text('To child page'),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My Child'),
      ),
      body: Center(
        child: TextButton(
          onPressed: () => Navigator.pushAndRemoveUntil(
              context,
              MaterialPageRoute(
                  builder: (BuildContext context) => MySecondChild()),
              ModalRoute.withName('/')),
          child: Text('Push to Second Child and remove until homepage'),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My Second Child'),
      ),
      body: Center(
        child: TextButton(
          onPressed: () => Navigator.pop(context),
          child: Text('Pop'),
        ),
      ),
    );
  }
}

考虑到人们可能遇到的其他情况并寻找解决方案来写这个答案。

如果您实现了自己的自定义 PageRoute/PageRoutBuilder 并在任何地方使用它来推送和弹出页面,建议的答案可能不起作用。至少,我的情况就是这样。

克服这个问题的一种方法是,像每个人(和文档本身)建议的那样使用命名路由。但不管“为什么”,如果你不想走那条路,我就来这里提出一个新的解决方案。

  1. 你可以给你的自己的PageRoute实现一个实例变量,比如说一个字符串(但不要。如果你真的想走这条路,至少使用枚举),这个变量将是你页面的名称(如 HomePageView)。稍后,当您希望 pushAndRemoveUntil until 时,将第二个参数写成如下所示:
Navigator.of(context).pushAndRemoveUntil(
    MyCustomPageBuilder(MyStatelessView()),
    (Route<dynamic> route) {
        if (route is MyCustomPageBuilder && route.instanceVariable == 'HomePageView') {
             return true;
        }
        return false;
    }
);
  1. 您可以将自定义 PageRoute 实现设计为通用的,并且在推送新页面时您可以编写:

Navigator.of(context).push(MyCustomPageBuilder<HomePageView>)

然后,在推动 MyStatelessView 并弹出前几页直到 HomePageView 时,您可以编写:

Navigator.of(context).pushAndRemoveUntil(
    MyCustomPageBuilder<MyStatelessView>(MyStatelessView()),
    (Route<dynamic> route) {
        if (route is MyCustomPageBuilder<HomePageView>) {
             return true;
        }
        return false;
    }
);

它们都可以工作。但我建议你选择第二个。