图1

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),
            ),
        );
    }
}