Flutter 路由总结

2021/7/14 flutter

# 通常使用路由

  • 页面跳转
///不带参数
Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context){
 return new Demo());
}))
1
2
3
4
  • 跳转并移除当前所有路由栈
Navigator.pushAndRemoveUntil(context,new MaterialPageRoute(builder: (BuildContext context) {
return new Demo();
}),(route) => route ==null);
1
2
3
  • 跳转并替换当前页面
Navigator.pushReplacement(context,new MaterialPageRoute(builder: (BuildContext context){
return new Demo();
}));
1
2
3

带参数跳转 需要Demo 定义接收参数

  • 路由返回
///不带参数返回
Navigator.pop(context);

///带参数返回
Navigator.pop(context,可选位置传参数);
1
2
3
4
5
  • 路由返回 接收参数

使用 awiat 或者 then 接收返回的参数

  • 命名路由跳转 接收参数
ModalRoute.of(context).settings.argument
1
  • 页面跳转 接收参数

读取预先定义好的参数 widget.xxx或者xxx 获取

  • 封装使用
import 'package:flutter/material.dart';
import 'package:flutter/animation.dart';

class NavigationUtil {
  static push(BuildContext context, Widget page, {Function callback}) {
    pushFromRight(context, page, callback);
  }

  static pushNoAnimate(BuildContext context, Widget page,
      {Function callback}) {}

  ///自定义跳转动画
  static pushFromRight(BuildContext context, Widget page, Function callback) {
    PageRouteBuilder pageBuilder = new PageRouteBuilder(
        opaque: false,
        transitionDuration: const Duration(microseconds: 2000),
        pageBuilder: (BuildContext context, _, __) {
          return page;
        },
        transitionsBuilder: (
          _,
          Animation animation,
          __,
          Widget child,
        ) {
          return new SlideTransition(
            position: new Tween(
              begin: const Offset(1.0, 0.0),
              end: Offset.zero,
            ).animate(animation),
            child: child,
          );
        });

    Navigator.of(context).push(pageBuilder).then((data) {
      callback != null && callback(data);
    });
  }

  ///自定义跳转动画
  static pushFromBottom(BuildContext context, Widget page,
      {Function callback}) {
    PageRouteBuilder pageBuilder = new PageRouteBuilder(
        opaque: false,
        pageBuilder: (BuildContext context, _, __) {
          return page;
        },
        transitionsBuilder: (
          _,
          Animation animation,
          __,
          Widget child,
        ) {
          return new SlideTransition(
            position: new Tween(
              begin: const Offset(0.0, 1.0),
              end: Offset.zero,
            ).animate(animation),
            child: child,
          );
        });

    Navigator.of(context).push(pageBuilder).then((data) {
      if (callback != null) {
        callback(data);
      }
    });
  }

  ///销毁所有页面,并跳转到page页
  static reset(BuildContext context, Widget page) {
    Navigator.of(context).pushAndRemoveUntil(
        new MaterialPageRoute(builder: (context) {
      return page;
    }), (Route route) => false);
  }

  ///销毁所有除了page的所有页面
  static popToPage(BuildContext context, Widget page) {
    Navigator.of(context).pushAndRemoveUntil(
        new MaterialPageRoute(builder: (context) {
      return page;
    }), (Route route) => false);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

# 通常使用路由进阶

import 'package:flutter/material.dart';

class AnimationRoutes extends PageRouteBuilder {
  final Widget widget;

  AnimationRoutes(this.widget)
      : super(
            transitionDuration: const Duration(milliseconds: 500), //设置动画时长500毫秒
            pageBuilder: (BuildContext context, Animation<double> animation1,
                Animation<double> animation2) {
              return widget;
            },
            transitionsBuilder: (BuildContext context,
                Animation<double> animation1,
                Animation<double> animation2,
                Widget child) {
              //渐变过渡
//      return FadeTransition(//渐变过渡 0.0-1.0
//        opacity: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
//          parent: animation1, //动画样式
//          curve: Curves.fastOutSlowIn, //动画曲线
//        )),
//        child: child,
//      );
              //翻转缩放
//      return RotationTransition(
//        turns: Tween(begin: 0.0, end: 1.0).
//        animate(
//          CurvedAnimation(
//            parent: animation1,
//            curve: Curves.fastOutSlowIn,
//          )
//        ),
//        child: ScaleTransition(
//          scale: Tween(begin: 0.0, end: 1.0).
//          animate(CurvedAnimation(parent: animation1, curve: Curves.fastOutSlowIn)),
//          child: child,
//        ),
//      );
              //左右滑动
              return SlideTransition(
                position: Tween<Offset>(
                        begin: Offset(-1.0, 0.0), end: Offset(0.0, 0.0))
                    .animate(CurvedAnimation(
                        parent: animation1, curve: Curves.fastOutSlowIn)),
                child: child,
              );
            });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

官网 (opens new window)

博客 (opens new window)

# 使用第三方框架

# 路由拦截

  • 属性介绍
属性 类型 说明
child Widget 子级 Widget
onWillPop WillPopCallback return 一个 bool 返回false 不能返回路由
  • 源码
const WillPopScope({
Key? key,
required this.child,
    equired this.onWillPop,
}) : assert(child != null),
    super(key: key);
    
1
2
3
4
5
6
7
  • 例子
///弹窗提示
new WillPopScope(
    onWillPop: () {
        return showDialog(
          context: context,
          builder: (context) => new AlertDialog(
            content: new Text(S.of(context).isExitTheRoom),
            actions: <Widget>[
              new TextButton(
                onPressed: () => Navigator.of(context).pop(false),
                child: new Text(
                  S.of(context).cancel,
                  style: PublicWgt.textStyle(color: AppColor.grey_99, size: 26),
                ),
              ),
              new TextButton(
                onPressed: () {
                  PublicFunc().directQuitRoom(live);
                  Navigator.of(context).pop(true);
                },
                child: new Text(
                  S.of(context).confirm,
                  style: PublicWgt.textStyle(color: AppColor.theme, size: 26),
                ),
              ),
            ],
          ),
        ) ??
        false;
    },
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
///GlobalKey 形式
GlobalKey<NavigatorState> _key = GlobalKey();

new WillPopScope(
    onWillPop: ()async {
      if (_key.currentState.canPop()) {
              _key.currentState.pop();
              return false;
            }
        return true;
    },
)
1
2
3
4
5
6
7
8
9
10
11
12
///双击形式
new WillPopScope(
    onWillPop: () async{
     if (_lastQuitTime == null ||
          DateTime.now().difference(_lastQuitTime).inSeconds > 1) {
        print('再按一次 Back 按钮退出');
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text('再按一次 Back 按钮退出')));
        _lastQuitTime = DateTime.now();
        return false;
      } else {
        print('退出');
        Navigator.of(context).pop(true);
        return true;
      }
    },
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Last Updated: 2021/7/15 16:04:19