欢迎您光临深圳塔灯网络科技有限公司!
电话图标 余先生:13699882642

网站百科

为您解码网站建设的点点滴滴

Flutter学习笔记之路由简单实用

发表日期:2018-12 文章编辑:小灯 浏览次数:2546

路由的简单实用

  • 基本的界面跳转
class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("first Screen"), ), body: Center( child: RaisedButton( child: Text("this is first screen"), onPressed: () { //go to second screen Navigator.push(context, MaterialPageRoute(builder: (context)=>SecodeScreen())); }, )), ); } } 
Screenshot_1545962905.png

如上图所示,第一个界面中包含了一个按钮,在按钮的点击事件中

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

这句代码的意思将页面SecondScreen压入路由栈,在Android开发中我们也是同样的使用一个回退栈管理我们的界面,既然有入栈操作,那么一定有出栈了,没错,下面看第二个界面的代码:

class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("second screen"), ), body: Center( child: RaisedButton( child: Text("go back"), onPressed: () { Navigator.pop(context); }, ), ), ); } } 

我们使用了

 Navigator.pop(context); 

将该本页面弹出路由栈,从而返回到第一个页面。
以上就是例子可以在官方文档中找到,这只是最简单的路由跳转,但是平时我们开发经常需要在页面之间传值,所以下面我们来看看,flutter中路由如何传递参数。

  • 传递参数到新页面
    我们继续使用官方的例子,首先定义一个实体类,
class Todo{ final String title; final String desc; Todo(this.title,this.desc); } 

然后我们创建一个todoList

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: TodoScreen( todos: List.generate(10, (i) => Todo("title$i", "Desc$i"))), ); } } //列表页 class TodoScreen extends StatelessWidget { final List<Todo> todos; TodoScreen({Key key, @required this.todos}) : super(key: key);@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("todos"), ), body: ListView.builder( itemCount: todos.length, itemBuilder: (context, index) { return ListTile( title: Text(todos[index].title), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => DetailScreen(todo: todos[index]))); }, ); }, ), ); } }//详情页 class DetailScreen extends StatelessWidget { final Todo todo; DetailScreen({Key key, @required this.todo}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(todo.title), ), body: Center( child: Text(todo.desc), ), ); } } 

在代码里我们通过

Navigator.push( context, MaterialPageRoute( builder: (context) => DetailScreen(todo: todos[index]))); }, ); 

将todo传到了详情页,也就是通过构造函数传值,在flutter中一切都是widget,我们在DetailScreen里通过构造函数接收即可。

  • 携带参数返回
    在Android开发中,我们通常使用startActivityForResult启动新页面,这样可以在当前中重写onActivityForResult来接收新页面返回的参数,那么在Flutter中该怎么坐呢,答案是使用Navigator.Pop(),
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: HomeScreen(), ); } }class SelectionButton extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return RaisedButton( child: Text('pick an option,any option'), onPressed: () { _navigateAndDisplaySelection(context); }, ); } } _navigateAndDisplaySelection(BuildContext context) async{ final result= await Navigator.push(context,MaterialPageRoute(builder: (context)=>SelectionScreen()) ); Scaffold.of(context) ..removeCurrentSnackBar() ..showSnackBar(SnackBar(content:Text("$result"))); } class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: AppBar( title: Text('home screen'), ), body: Center(child: SelectionButton()), ); } } class SelectionScreen extends StatelessWidget{ @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: AppBar( title: Text("pick on option"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Padding( padding: const EdgeInsets.all(8.0), child: RaisedButton( onPressed: (){ Navigator.pop(context,"yep"); }, child: Text("yep"), ), ), Padding( padding: const EdgeInsets.all(8.0), child: RaisedButton( onPressed: (){ Navigator.pop(context,"nope"); }, child: Text("nope"), ), ) ], ), ), ); }} 

Pop方法的第二个参数是一个

T result 

这样我们在出栈的时候可以将参数带回到上一个页面,在上一个页面中,我们这样来接收

_navigateAndDisplaySelection(BuildContext context) async{ final result= await Navigator.push(context,MaterialPageRoute(builder: (context)=>SelectionScreen()) ); Scaffold.of(context) ..removeCurrentSnackBar() ..showSnackBar(SnackBar(content:Text("$result"))); } 
  • 命名路由
    首先我们先定义一个路由映射关系
class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData(primarySwatch: Colors.blue, ), home: FirstScreen(), routes: { '/second':(context)=>SecondScreen() }, ); } } 

routes是一个map,用来管理我们定义的命名路由,之后我们就可以使用

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

来进行路由的跳转,但是命名路由的方式有一个缺点,就是不能直接携带参数,只能静态的在注册路由的时候这么写:

 routes: { '/second':(context)=>SecondScreen('params') }, 

这样在传递一些动态的改变的参数时候就显得不方便。

  • Hero控件
    这个很像Android里的共享元素,比如页面A和页面B都有一张相同的图片,让他们之间跳转的时候,图片无缝过渡,在Flutter使用Hero可以实现这一效果。下面来看看代码中如何实现。
class HeroApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Transition Demo', home: MainScreen(), ); } }class MainScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Main Screen'), ), body: GestureDetector( child: Hero( tag: 'imageHero', child: Image.network( 'https://raw.githubusercontent.com/flutter/website/master/src/_includes/code/layout/lakes/images/lake.jpg', ), ), onTap: () { Navigator.push(context, MaterialPageRoute(builder: (_) { return DetailScreen(); })); }, ), ); } }class DetailScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: GestureDetector( child: Center( child: Hero( tag: 'imageHero', child: Image.network( 'https://raw.githubusercontent.com/flutter/website/master/src/_includes/code/layout/lakes/images/lake.jpg', ), ), ), onTap: () { Navigator.pop(context); }, ), ); } } 

在不同页面通过给Hero设置相同的tag,使它们关联起来。

总结

Flutter中路由的常用使用方式基本介绍完了,主要参考官方例子,如有不足,欢迎指正。

参考

Flutte Doc


本页内容由塔灯网络科技有限公司通过网络收集编辑所得,所有资料仅供用户学习参考,本站不拥有所有权,如您认为本网页中由涉嫌抄袭的内容,请及时与我们联系,并提供相关证据,工作人员会在5工作日内联系您,一经查实,本站立刻删除侵权内容。本文链接:http://dengtar.com/17608.html
上一篇:Flutter安装环境 下一篇:flutter前期准备
相关APP开发
 八年  行业经验

多一份参考,总有益处

联系深圳网站公司塔灯网络,免费获得网站建设方案及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

业务热线:余经理:13699882642

Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.