Flutter路由跳转及参数传递以及练习demo
Flutter路由介绍
Flutter里面有路由支持所有的路由场景,push、pop页面,页面间的参数传递等等。flutter里面的路由可以分成两种,一种是直接注册,不能传递参数。另一种要自己构造实例,可以传递参数。我们暂时把它们规为静态路由和动态路由。
静态路由的注册
在新建一个MD风格的App的时候,可以传入一个routes参数来定义路由。但是这里定义的路由是静态的,它不可以向下一个页面传递参数。
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter实例'),
routes: {
// 这里可以定义静态路由,不能传递参数
'/router/second': (_) => new SecondPage(),
'/router/home': (_) => new RouterHomePage(),
},
);
静态路由的使用
push一个新页面,pushNamed方法是有一个Future的返回值的,所以静态路由也是可以接收下一个页面的返回值的。但是不能向下一个页面传递参数。
Navigator.of(context).pushNamed('/router/second');
// 带返回值
Navigator.of(context).pushNamed('/router/second').then((value) {
// dialog显示返回值
_showDialog(context, value);
})
pop回上一个页面
Navigator.of(context).pop('这个是要返回给上一个页面的数据');
动态路由的使用
当需要向下一个页面传递参数时,要用到所谓的动态路由,自己生成页面对象,所以可以传递自己想要的参数。
Navigator.of(context).push(new MaterialPageRoute(builder: (_) {
return new SecondPage(title: '路由是个好东西,要进一步封装');
}));
也可以用PageRouterBuilder来自定义打开动画
Navigator.of(context).push(new PageRouteBuilder(pageBuilder:
(BuildContext context, Animation animation,
Animation secondaryAnimation) {
return new RefreshIndicatorDemo();
}, transitionsBuilder: (
BuildContext context,
Animation animation,
Animation secondaryAnimation,
Widget child,
) {
// 添加一个平移动画
return BRouter.createTransition(animation, child);
}));
平移的变换
/// 创建一个平移变换
/// 跳转过去查看源代码,可以看到有各种各样定义好的变换
static SlideTransition createTransition(
Animation animation, Widget child) {
return new SlideTransition(
position: new Tween(
begin: const Offset(1.0, 0.0), // const Offset(0.0, 0.0) 相当于Fadeout fadein
end: const Offset(0.0, 0.0),
).animate(animation),
child: child, // child is the value returned by pageBuilder
);
}
完整的源码
import 'package:flutter/material.dart';
import 'package:iw3c_blog_app/show.dart';
void main() => runApp(new MyAppBar());
//创建一个名为MyAppBar的类,无状态,用于页面的基本布局
class MyAppBar extends StatelessWidget{
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'My appBar', //APP的名称
theme: new ThemeData(
primarySwatch: Colors.red //定义 APP 的主题颜色
),
home: new MyAppBarHome() //APP的默认页
);
}
}
// 创建MyAppBarHome类, 这是 APP 的默认页,有状态的,因为我们做一些交互操作,必须有状态
class MyAppBarHome extends StatefulWidget{
@override
MyAppBarHomeState createState() => new MyAppBarHomeState();
}
// MyAppBarHome的状态类
class MyAppBarHomeState extends State{
// Scaffold key 定义一个脚手架的key,相当于html中元素的id吧
GlobalKey _scaffoldKey = new GlobalKey();
// @function 打开Drawer组件,下面要用到
void _openDrawer(){
_scaffoldKey.currentState.openEndDrawer(); // open the drawer
}
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey, //为脚手架设置key
appBar: new AppBar(
leading: new Icon(Icons.home), //为appBar定义一个图标
title: new Text('Flutter appBar widget'), //appBar的标题
centerTitle: true, //appBar标题居中
actions: [ //向aciont中放了一个简单的图标按钮IconButton,它的方法(onPressed)为打开Drawer
new IconButton(
icon: new Icon(
Icons.menu,
color: Colors.white,
),
onPressed: _openDrawer
)
],
),
//一共有两种Drawer,一种是drawer,从app的左侧滑出,一种是endDrawer,从右侧滑出,我这里用的是从右侧出滑出的
//drawer: new Drawer,
endDrawer: new Drawer(
child: new ListView(
children: [
new ListTile(
title: new Text("欢迎"),
),
new Divider(),
new ListTile(
title: new Text("设置"),
trailing: new Icon(Icons.settings),
onTap: () {}),
],
),
),
body: new Center(
child: new Text(
'赵客缦胡缨,吴钩霜雪明',
style: new TextStyle(
fontSize: 24.0,
color: Colors.red
),
),
),
floatingActionButton: new FloatingActionButton(
onPressed: (){
Navigator.of(context).push(new PageRouteBuilder(
pageBuilder: (BuildContext content, Animation animation, Animation secondaryAnimation){
return new TestShow('sunmoon');
},
transitionsBuilder: (_, Animation animation, __, Widget child) {
return new FadeTransition(
opacity: animation,
child: new SlideTransition(position: new Tween(
begin: const Offset(0.0, 0.0),
end: Offset.zero,
).animate(animation), child: child),
);
}
));
},
tooltip: 'Increment',
child: new Icon(Icons.add),
),
);
}
}