Flutter核心技术与实战
陈航
美团点评高级技术专家
立即订阅
6150 人已学习
课程目录
已完结 47 讲
0/4登录后,你可以任选4讲全文学习。
课前必读 (3讲)
开篇词 | 为什么每一位大前端从业者都应该学习Flutter?
免费
01 | 预习篇 · 从0开始搭建Flutter工程环境
02 | 预习篇 · Dart语言概览
Flutter开发起步 (3讲)
03 | 深入理解跨平台方案的历史发展逻辑
04 | Flutter区别于其他方案的关键技术是什么?
05 | 从标准模板入手,体会Flutter代码是如何运行在原生系统上的
Dart语言基础 (3讲)
06 | 基础语法与类型变量:Dart是如何表示信息的?
07 | 函数、类与运算符:Dart是如何处理信息的?
08 | 综合案例:掌握Dart核心特性
Flutter基础 (13讲)
09 | Widget,构建Flutter界面的基石
10 | Widget中的State到底是什么?
11 | 提到生命周期,我们是在说什么?
12 | 经典控件(一):文本、图片和按钮在Flutter中怎么用?
13 | 经典控件(二):UITableView/ListView在Flutter中是什么?
14 | 经典布局:如何定义子控件在父容器中排版的位置?
15 | 组合与自绘,我该选用何种方式自定义Widget?
16 | 从夜间模式说起,如何定制不同风格的App主题?
17 | 依赖管理(一):图片、配置和字体在Flutter中怎么用?
18 | 依赖管理(二):第三方组件库在Flutter中要如何管理?
19 | 用户交互事件该如何响应?
20 | 关于跨组件传递数据,你只需要记住这三招
21 | 路由与导航,Flutter是这样实现页面切换的
Flutter进阶 (17讲)
22 | 如何构造炫酷的动画效果?
23 | 单线程模型怎么保证UI运行流畅?
24 | HTTP网络编程与JSON解析
25 | 本地存储与数据库的使用和优化
26 | 如何在Dart层兼容Android/iOS平台特定实现?(一)
27 | 如何在Dart层兼容Android/iOS平台特定实现?(二)
28 | 如何在原生应用中混编Flutter工程?
29 | 混合开发,该用何种方案管理导航栈?
30 | 为什么需要做状态管理,怎么做?
31 | 如何实现原生推送能力?
32 | 适配国际化,除了多语言我们还需要注意什么?
33 | 如何适配不同分辨率的手机屏幕?
34 | 如何理解Flutter的编译模式?
35 | Hot Reload是怎么做到的?
36 | 如何通过工具链优化开发调试效率?
37 | 如何检测并优化Flutter App的整体性能表现?
38 | 如何通过自动化测试提高交付质量?
Flutter综合应用 (6讲)
39 | 线上出现问题,该如何做好异常捕获与信息采集?
40 | 衡量Flutter App线上质量,我们需要关注这三个指标
41 | 组件化和平台化,该如何组织合理稳定的Flutter工程结构?
42 | 如何构建高效的Flutter App打包发布环境?
43 | 如何构建自己的Flutter混合开发框架(一)?
44 | 如何构建自己的Flutter混合开发框架(二)?
结束语 (1讲)
结束语 | 勿畏难,勿轻略
特别放送 (1讲)
特别放送 | 温故而知新,与你说说专栏的那些思考题
Flutter核心技术与实战
登录|注册

21 | 路由与导航,Flutter是这样实现页面切换的

陈航 2019-08-15
你好,我是陈航。
在上一篇文章中,我带你一起学习了如何在 Flutter 中实现跨组件数据传递。其中,InheritedWidget 适用于子 Widget 跨层共享父 Widget 数据的场景,如果子 Widget 还需要修改父 Widget 数据,则需要和 State 一起配套使用。而 Notification,则适用于父 Widget 监听子 Widget 事件的场景。对于没有父子关系的通信双方,我们还可以使用 EventBus 实现基于订阅 / 发布模式的机制实现数据交互。
如果说 UI 框架的视图元素的基本单位是组件,那应用程序的基本单位就是页面了。对于拥有多个页面的应用程序而言,如何从一个页面平滑地过渡到另一个页面,我们需要有一个统一的机制来管理页面之间的跳转,通常被称为路由管理或导航管理
我们首先需要知道目标页面对象,在完成目标页面初始化后,用框架提供的方式打开它。比如,在 Android/iOS 中我们通常会初始化一个 Intent 或 ViewController,通过 startActivity 或 pushViewController 来打开一个新的页面;而在 React 中,我们使用 navigation 来管理所有页面,只要知道页面的名称,就可以立即导航到这个页面。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Flutter核心技术与实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(18)

  • YJ
    使用的是Navigator.push
     A->B->C->D,
    请问如何 D页面 pop 到 B 呢?

    作者回复: Navigator.popUntil(context,ModalRoute.withName('B'));

    2019-08-19
    7
  • 入魔的冬瓜
    自己手动push一个route的话,可以通过构造函数进行传参数。
    使用命名路由的话,参数的读取通过ModalRoute.of(context).settings.arguments,这个操作要放在build里面操作。这种情况,有没有什么办法也是通过构造函数传参数,在build之前就可以拿到参数。(类似第三方fluro框架)

    作者回复: 命名路由没有提供这样的接口,如果想这样做的话,可以自己实现一套注册路由的注解,在编译期初始化页面的时候把参数传过去

    2019-10-18
    2
  • 和小胖
    在敲代码时候的有两点需要注意的地方。

    1、在传入 runApp 里面的 widget 里面做路由跳转的时候所使用的的 BuildContext 不能是 App 的,必须得是 widget 的,否则会报 Navigator operation requested with a context that does not include a Navigator 这样子的错。

    2、使用命名路由或者注册表的方式,最好是在传入 runApp 里面的 widget 的MaterialApp 里面做 routes 的配置,为的是 APP 一启动的时候就注册上,否则可能会存在要使用命名,可是还没注册的情况,就会报 Could not find a generator for route RouteSettings("second_page", null) in the _WidgetsAppState 这样的错误。

    作者回复: 赞👍

    2019-09-24
    2
  • 把所有命名路由都定义在一起会很多,也不利于模块化,能否在模块中定义路由呢?另外,有没有子路由的概念呢?

    作者回复: 你可以试试用注解的方式结偶,在运行期统一收集注册

    2019-10-22
  • 老师你好,showdialog也是进行了路由跳转,为什么会出现在当前界面上面,而普通的都是跳到另外一个新的界面

    作者回复: 底层element与render object渲染的样式不一样而已

    2019-10-21
  • 巫山老妖
    第二道思考题:
    传参:
    RaisedButton(
                child: Text('命名路由(参数&回调)'),
                onPressed: () =>
                    Navigator.pushNamed(context, "third_page", arguments: [1, 2])
                        .then((msg) {
                  setState(() {
                    _msg = msg;
                  });
                })

    计算并返回:

    class ThirdPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        var args = ModalRoute.of(context).settings.arguments as List<int>;

        int sum = args[0] + args[1];
        print(sum);

        return Scaffold(
          appBar: AppBar(
            title: Text('Third Screen'),
          ),
          body: Column(
            children: <Widget>[
              Text('Message from first screen: $args'),
              RaisedButton(
                child: Text('back'),
                onPressed: ()=> Navigator.pop(context, "${sum}"),
              )
            ],
          ),
        );
      }
    }

    作者回复: 赞👍

    2019-10-07
  • 严旭珺
    老师好,请问一下,如果是类似于Android中打开页面 A->B->A,标准的启动模式,栈中有2个A页面该怎么办呢?我试了试B页面Navigator.pushName(context,A),会黑屏

    作者回复: 有几个A都可以啊,因为每个A都是不同的实例。

    2019-10-05
  • 和小胖
    第二个问题:可以构造一个 list 传递过去,然后对 list 中数据的两个数字求和再把结果带回上个页面。

    另外老师通过 arguments 是不是只能传递一个参数呀?

    作者回复: 只能传一个参数,如果需要多个参数,传Map或者List都可以

    2019-09-24
  • 高超
    问:对于基本路由,如何传递页面参数?
    答:1. 使用构造函数传参
          2. MaterialPageRoute 加入参数 setting: RouteSettings 。第二个页面获取逻辑和命令路由就一样了。

    作者回复: 赞

    2019-09-03
  • YJ
    原来是个使用是可以混合使用的
    Navigator.push(context, MaterialPageRoute(builder: (BuildContext context){
                          return CarStockPage();
                        }));
    Navigator.pushNamed(context, YJRouters.clue_page);
    两种方式结合场景可以混合使用,就可以满足相当复杂的路由跳转逻辑了!!!
    2019-08-28
  • 大恒数据
    讲的简单了一点,YJ同学的问题才是实际场景遇到的
    2019-08-28
  • YJ
    陈老师请问?
    使用的是Navigator.push
     A->B->C->D,
    如何 让D页面 pop 到 B 呢?

    作者回复: Navigator.popUntil(context,ModalRoute.withName('B'));

    2019-08-20
    2
  • 汪帅
    其实我一直想知道这个课程的样例代码在哪里?之前见过有人留言中问过但是也没看到有回复具体地址。现在找那条留言也找不到了,其它课程都有对应的样例代码在github上面,如果有在每篇下面附加上代码地址不可以么?

    作者回复: 谢谢你的建议,课程的样例代码参见
    https://github.com/cyndibaby905/flutter_core_demo

    2019-08-18
  • 竹之同学
    对于基本路由,其实路由返回的就是那个新页面初始化的实例,所以可以在页面 Widget 定义变量,然后在路由返回,也就是实例化的时候传值进去。

    作者回复: 对的

    2019-08-16
  • Mr.J
    在新建页面的时候通过构造函数传的参数

    作者回复: 对的

    2019-08-15
  • 亡命之徒
    class MySecondPage extends StatelessWidget {
      String msg;
      MySecondPage({
        Key key,
        this.msg
      }):super(key:key);
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        MyThreePage tsp = new MyThreePage();
        //基本路由传递参数
        tsp.msg = "我来自第二个页面";
        return Scaffold(
          appBar: AppBar(title: Text("SecondPage"),),
          body: RaisedButton(
            child: Text("MyEvent Bus$msg"),
            onPressed: () {
              myEventBus.fire(MyCustomEvent("Hello World"));
              Navigator.pop(context);
            },
          ),
          floatingActionButton: FloatingActionButton(
            child: Icon(Icons.pages),
            onPressed: (){
              Navigator.push(context, MaterialPageRoute(builder: (context)=>tsp));
            },
          ),
        );
      }
    }

    MySecondPage sp = new MySecondPage();
        sp.msg = "我传给你了哈哈哈";
    onPressed: ()=>Navigator.push(context,MaterialPageRoute(builder: (context)=>sp)),
    可以通过这种方式传递

    作者回复: 赞,不过直接通过构造函数传进去会更好

    2019-08-15
  • colin
    context 会细讲吗? 感觉不是很懂

    作者回复: 理解成创建widget的上下文就可以了。context实际是element,是为了阻止直接对element操作而抽象出来的一个概念

    2019-08-15
  • 许童童
    对于基本路由,如何传递页面参数?
    能过MaterialPageRoute 的 settings 属性。

    作者回复: 初始化的时候直接通过属性传值就可以了

    2019-08-15
收起评论
18
返回
顶部