Flutter-路由跳转


路由跳转

前端页面开发中,路由的概念并不陌生,比如Android中经常会封装一些路由框架,通过一个name跳转指定的Acitivity以进行一定程度的解耦.

在Flutter中同样也有路由的概念,但是由于Dart语言比较古老落后,Flutter的路由跳转在一定程度上比较丑陋.

在Flutter中,我们一般使用Navigator进行路由跳转.

最简单的跳转方法

    Navigator.of(context).push(MaterialPageRoute(builder: (context) {
      return page;
    }));

使用一个封装好的MaterialPageRouter作为Router的实现.

当要返回时,可以用pop:

Navigator.pop(context);

或者:

 Navigator.of(context).pop();

使用路由名字进行跳转

当项目中的页面比较多的时候,如果再用上面的方法进行跳转,到后面就很难维护了,不利于拓展,因为我们必须引用到指定的页面Widget.

很容易想到,Flutter的Navigator提供了一个方法,使用一个routerName就可以跳转到指定的页面Widget,而不需要直接依赖页面Widget,这就需要建立一个name到页面的映射了,我们一般在APP的入口处进行设置:

MaterialApp(
  // Start the app with the "/" named route. In this case, the app starts
  // on the FirstScreen widget.
  initialRoute: '/',
  routes: {
    // When navigating to the "/" route, build the FirstScreen widget.
    '/': (context) => FirstScreen(),
    // When navigating to the "/second" route, build the SecondScreen widget.
    '/second': (context) => SecondScreen(),
  },
);

当需要跳转的时候,执行下面的方法:

Navigator.pushNamed(context, '/second');

当需要返回的时候,执行下面的方法:

Navigator.pop(context);

传参跳转

页面直接的跳转不免会遇到需要传递参数的情形,如果是直接跳转,直接在页面的构造方法中传入参数即可.

传递的参数是一个Object,可以是你自己定义的类实例,也可以是数字,字符串等:

Navigator.of(context).pushNamed("/demo", arguments: data);

对于不带名字的路由跳转,可以通过RouteSettings进行传参:

        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => DetailScreen(),
            // 传参args
            settings: RouteSettings(
              arguments: args,
            ),
          ),
        );

那么如何在页面中获取到传入的参数呢?

答案是需要使用ModalRoute.of(context):

final Object args = ModalRoute.of(context).settings.arguments

其中args可以是任何你定义的类,假设这里要传入的是一个Dog对象:

class Dog {
  String name;
  int age;

  Dog(this.name, this.age);
}

那些的时候就可以是:

final Dog dog = ModalRoute.of(context).settings.arguments;
String name = dog.name;
int age = dog.age;

除了在页面Widget中解析参数以外,还可以在MaterialApp#onGenerateRoute()中:

使用MaterialApp#onGenerateRoute()

MaterialApp(
  onGenerateRoute: (settings) {
    if (settings.name == "/dog") {
      final Dog dog = settings.arguments;
      return MaterialPageRoute(
        builder: (context) {
          return DogPage(
            name: dog.name,
            age: dog.age,
          );
        },
      );
    }
  },
);

其实不管是在页面中解析参数,还是在onGenerateRoute中解析参数,我们需要都只是一个RouteSettings对象,这个对象中持有了路由名字和传递的参数,因此可以通过它将两者联系起来:

class RouteSettings {

  const RouteSettings({
    this.name,
    this.arguments,
  });

  final String name;

  final Object arguments;

  
  String toString() => '${objectRuntimeType(this, 'RouteSettings')}("$name", $arguments)';
}

返回路由结果

在Android中跳转Activity,在返回到当前页的时候需要从页面带回来一些数据,Android中是通过onActivityForResult实现的,在Flutter中则是通过异步函数调用实现的.在跳转的时候保存一个Future对象的结果即可:

final result = await Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => SelectionScreen()),
  );

那么在页面退出/返回的时候任何传递结果呢?

答案是pop方法中可以携带一个结果对象,类型可以自定义:

 Navigator.of(context).pop<T>(result);

文章作者: 姜康
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 姜康 !
评论
 上一篇
Flutter-区分Debug,Release,Profile模式 Flutter-区分Debug,Release,Profile模式
Flutter中如果需要在Debug模式下输出一些信息,或者做一些特殊的逻辑,但是Release模式下又不需要的话,就需要可以判断当前的APK或者ipa是否为debug模式.这里有两种方式可以用来判断: 使用dart.vm.product属
2020-07-18
下一篇 
Flutter-转场动画(页面跳转动画) Flutter-转场动画(页面跳转动画)
在Android中专场动画比较常见,就是从一个Activity/Fragment跳转到另一个Activity/Fragment之间的过渡状态.Flutter也提供了对转场动画的支持. 路由跳转的一般方式Navigator.of(contex
2020-07-12
  目录