Flutter 页面跳转小结

The Navigation between Flutter Routes

Navigation 纵览

容易想象到的是,客户端的导航逻辑具有相似性。对具有原生app经验的开发者来说,它可以类比于 native app 开发中的“页面”跳转(Android 中的 Activity, iOS 中的 ViewController)。同样UI层面的概念在Flutter也出现了,它就是 Route其关联的有Widget, 较为常见的Widget有 StatelessWidget 或是 StatefulWidget ;同时与跳转逻辑相关的还有Navigator, 而 Navigator 本身也是一个Widget (Flutter中 Widget无处不在!),它遵循Stack栈的规则管理着一系列子Widget。

最直接的页面跳转方式

使用 MaterialPageRoute :

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

Route 利用一个builder方法定义自身的Widget,而非直接传入一个子Widget, 这是因为基于自身被Pushed 或是 Popped的不同context环境下,它会被构建以及重建(built and rebuilt)。

具名的 Route

手机上的App通常会有大量的Route, 而通过名字去找到相应的Route往往也更容易。按照约定Route的名字和路径的表示(path-like structure)比较相像。"/" 用以表示 App 的Home页面的Route。

MaterialApp 在创建的时候可以指定其 routes (结构为 Map),它保留了 Route的名字与 创建对应Widget build 方法的映射关系。

 MaterialApp(
   home: MyAppHome(), // becomes the route named '/'
   routes:   {
     '/a_route_name': (BuildContext context) => YourWidget(),
   },
 )

按名字显示一个Route :

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

参数传递

设置传入参数

同样使用 MaterialPageRoute,可以设置其可选参数settings 传入参数:

MaterialPageRoute(
  builder: (BuildContext context) {
    return YourWidget();
  },
  settings: RouteSettings(arguments: your_param_object),
);

对于具名的Route,类似的方法有:

Navigator.pushNamed(context, routeName, arguments: your_param_object);

读取传入的参数

class MyWidget {
  @override
  Widget build(BuildContext context) {
    final MyArgs args = ModalRoute.of(context).settings.arguments;
    // ...
  }
}

设置传出的参数

在第2个Widget中 (SelectionScreen) 设定返回值

Navigator.pop(context, 'Yep!');

在首个Widget中接收:

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

  // After the Selection Screen returns a result, hide any previous snackbars
  // and show the new result.
  Scaffold.of(context)
    ..removeCurrentSnackBar()
    ..showSnackBar(SnackBar(content: Text("$result")));
}

更多 Navigation 相关的方法

  • Navigator.popAndPushNamed(context, routeName);
  • Navigator.of(context).pushNamedAndRemoveUntil(HomeScreen.routeName, (_) => false);
  • Navigator.of(context).pushReplacement(newRoute)

参考引用

  • Flutter Doc

  • Flutter Tutorial: Multiple Screens and How-To Navigate Them

你可能感兴趣的:(Flutter 页面跳转小结)