TreeviewCopyright © aleen42 all right reserved, powered by aleen42

Route

在 Android 中,我们将每个页面抽象成一个 Activity,Android 系统维护了一个 Activity 栈,Activity 在栈中进行出栈入栈操作,来完成页面之间的跳转。在 Flutter 中,页面被抽象成为一个 Route,Route 的管理交由一个维护了 Route 栈的管理组件 —— Navigator(Navigator 后面会讲到),通过出栈入栈,来完成 Route 之间的跳转。

在 Android 中,我们创建完 Activity 之后还必须在清单文件中声明,在 Flutter 中,有两种方式,我把它们分为:

  • 静态路由(也有的地方叫命名路由)
  • 构建路由(也有的地方叫基本路由)

在之前的例子中,main 方法我们是这么写的:

void main() {
  runApp(new MaterialApp(
    home: new XXXXX(),
  ));
}

这个 home 参数指定了我们的“主页面”,Flutter 还提供了另外一种将路由写死在路由表中的方法,在 MaterialApp 中有一个参数 routes,用它来设置每个页面的 key 和具体页面(Route),是这样写的:

void main() {
  runApp(new MaterialApp(
    routes: <String,WidgetBuilder>{
      "/":(BuildContext context) => new FirstRoute(),
      "/Second":(BuildContext context) => new SecondRoute(),
      "/Third":(BuildContext context) => new ThirdRoute(),
    },
  ));
}

这种方式称之为“命名路由/静态路由”,其使用方法需要注意以下几点:

  1. 通常情况下,我们将跟路由(主界面)命名为 /,其余路由和 REST API 开发中的路由类似,/A 代表 ARoute/B 代表 BRoute
  2. 当然你的跟路由也可以命名成别的方式,但如果跟路由不是 / 的话,需要使用 MaterialApp 中的 initialRoute 来声明跟路由。
  3. routeshome 属性不能共存,否则会报错。

Route 声明好了,接下来就是从一个 Route 跳转到另一个 Route 了,Flutter 提供了 Navigator 组件来帮助我们完成这一操作,它维护了一个 Route 栈,通常情况下,我们启动一个新页面,就将该 Route 压入到栈顶,退出该页面,则从栈顶弹出该 Route(就和 Android 默认的启动模式一样,Android 中其他启动模式也有,稍后会讲到)。

基本入栈

Navigator 维护了一个 Route 栈,从一个 Route 跳转到另一个 Route,默认情况下就是一个目标 Route 的入栈操作,目标 Route 会进入到栈顶,Navigator 提供了两个方法来帮助我们完成这一基础操作:

  • Navigator.pushNamed,适用于命名路由

    Navigator.pushNamed(context, "SecondRoute");    /// SecondRoute 需要提前在 routes 中声明
    
  • Navigator.push,适用于构建路由

    Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => SecondRoute(),
        ),
    );
    

    在上面的代码中用到了 MaterialPageRoute,后面会讲到。

基本出栈

有入栈就有出栈,出栈可以调用 Navigatorpop 方法:

Navigator.pop(context);

需要注意的是,当路由栈内只有一个 Route 的时候,执行 pop 方法并不会像 Android 那样退出 APP,而是会显示黑屏,所以我们在执行 pop 操作的时候,最好先调用一下 Navigator.canPop() 方法,确实是否可以执行 pop 操作,该方法返回了一个 bool 值。

既然 pop 方法不能退出 APP,那我们想要退出 APP 该如何操作呢?有两种方法:

  1. SystemNavigator.pop(需要引入 import 'package:flutter/services.dart';)
  2. onPressed: ()=> exit(0),,不推荐,容易引起 APP 崩溃

复杂出入栈

Flutter 还提供了其他一些可以帮助我们进行复杂出栈入栈操作的方法,下面分别介绍一下:

  • pushReplacement
  • pushReplacementNamed

这两个方法都是将一个路由加入到栈顶,并将当前路由出栈(pop)。(也就是以一个新页面替换当前页面。在新页面的入场动画结束时,才会调用当前页面的dispose方法。),一个适用于命名路由,一个适用于构建路由。


  • pushAndRemoveUntil

  • pushNamedAndRemoveUntil

这两个方法同样是一个适用于命名路由,一个适用于构建路由。

第一个参数是 context

第二个参数是需要目标路由(一个是命名路由的 key,一个是构建路由构建的 Route)

第三个参数是重点:

  • 当使用 (Route<dynamic> route) => false 时,路由栈全部清空,再将目标路由入栈,此时路由栈内只有目标路由自己。
  • 当使用 ModalRoute.withName('XXX') 时,将目标路由加入到栈顶,并将其下方的路由逐一出栈,直到遇到名为 XXX 的路由。

  • replace
  • replaceRouteBelow

这两个方法都是以一个新路由替换路由栈中已经存在的路由,但查资料发现都需要获取 oldRoute 对象,暂时还不知道该如何使用,写了几个例子都是出错,等学会了再来更新


  • popUntil

该方法会一直调用 pop 方法对路由栈内的路由进行出栈,直到 predicate 函数返回了 true。使用方法:

///一直出栈,直到 /
Navigator.popUntil(context, ModalRoute.withName("/"));

  • popAndPushNamed

将当前路由出栈,并将一个新路由加入到栈顶。使用方法:

Navigator.popAndPushNamed(context, "/");

此时栈顶为名为 / 的 Route


  • removeRoute
  • removeRouteBelow

这两个方法是将指定的路由从任务栈中移除。这两个方法和 replacereplaceRouteBelow 一样,需要获取移除对象的实例。

results matching ""

    No results matching ""