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核心技术与实战
登录|注册

30 | 为什么需要做状态管理,怎么做?

陈航 2019-09-05
你好,我是陈航。
在上一篇文章中,我与你分享了如何在原生混编 Flutter 工程中管理混合导航栈,应对跨渲染引擎的页面跳转,即解决原生页面如何切换到 Flutter 页面,以及 Flutter 页面如何切换到原生页面的问题。
如果说跨渲染引擎页面切换的关键在于,如何确保页面跳转的渲染体验一致性,那么跨组件(页面)之间保持数据共享的关键就在于,如何清晰地维护组件共用的数据状态了。在第 20 篇文章“关于跨组件传递数据,你只需要记住这三招”中,我已经与你介绍了 InheritedWidget、Notification 和 EventBus 这 3 种数据传递机制,通过它们可以实现组件间的单向数据传递。
如果我们的应用足够简单,数据流动的方向和顺序是清晰的,我们只需要将数据映射成视图就可以了。作为声明式的框架,Flutter 可以自动处理数据到渲染的全过程,通常并不需要状态管理。
但,随着产品需求迭代节奏加快,项目逐渐变得庞大时,我们往往就需要管理不同组件、不同页面之间共享的数据关系。当需要共享的数据关系达到几十上百个的时候,我们就很难保持清晰的数据流动方向和顺序了,导致应用内各种数据传递嵌套和回调满天飞。在这个时候,我们迫切需要一个解决方案,来帮助我们理清楚这些共享数据的关系,于是状态管理框架便应运而生。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Flutter核心技术与实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(17)

  • 小石头若海
    老师说的“事实上,当我们使用Provider后,我们就再也不需要使StatefulWidget了”这句不太合理吧。。。😂

    这是不是会导致Provider的滥用,还是应该把一些共享的数据放在Provider中,其他的交给组件自治更好

    作者回复: 哈,这是个夸张的语法,形容provider的强大:)实际上StatefulWidget的用途不仅是通过数据变更驱动UI更新,还涉及到状态流转的各个生命周期,这些provider是搞不定的。技术领域没有银弹,还是得看具体场景

    2019-09-05
    4
  • 🌝
    老师, ChangeNotifier中有dispose方法, 这个方法又应该在是情况下才使用的到?

    作者回复: 需要释放封装对象资源的时候,比如在用文件做持久化的场景。

    2019-10-16
    1
  • ray
    一直觉得Provider的Consumer~Consumer6不够优雅

    作者回复: 确实不优雅

    2019-09-05
    1
  • Carlo
    老师,我们在生产环境的项目比较大,我们通过建造一个DependencyProvider
    class DependencyProvider {
      DependencyProvider._();

      static DependencyProvider _sharedInstance;
      static DependencyProvider get sharedInstance {
        return _sharedInstance;
      }
      UserService get userService => UserService.sharedInstance(persistenceService);
    }

    然后通过在页面中注入页面所需的Service来共享数据
    DependencyProvider.sharedInstance.userService

    感觉也比较清晰,不知道您怎么评价这种机制?
    跟Provider相比的优劣势是什么呢?

    谢谢您的回复!

    作者回复: 以单例模式共享数据,本质上和全局变量共享数据类似,全局可见,读写效率高,适合代码量少、功能也少、相对比较简单的程序。
    对于代码量大、功能又多、逻辑又复杂的工程来说,就不建议用单例/全局变量了。主要有以下几个原因:
    1.代码对单例产生耦合依赖,破坏了代码的封装性/独立性
    2.变量的读写处于无序状态,每个模块都可以去读写数据,对系统维护及调试非常不利
    3.变量常驻内存,无法释放

    2019-11-25
  • Carlo
    能不能再解释下Provider.of ?获取对象不是按照数据类型来定的吧?比如如果我还有个lineHeight,那写成
    final _counter = Provider.of<CounterModel>(context);//获取计时器实例
    final textSize = Provider.of<double>(context);//获取字体大小
    final lineHeight = Provider.of<double>(context);
    照数据类型一样的情况下,如何知道我获取的是textSize还是lineHeight?

    作者回复: 包一个大对象就可以了

    2019-11-25
  • 🌝
    老师,Provider的数据会在跳转页面的时候清除掉。我该如何去处理这个问题?

    作者回复: 你检查下组件的生命周期看看是不是有销毁/新建

    2019-11-08
  • 离尘不离人คิดถึง
    final _counter = Provider.of<CounterModel>(context);
        return Scaffold(
          appBar: AppBar(
            title: Text('DataFlow Page2'),
          ),
          //展示资源中的数据
          body: Consumer<CounterModel>(
            builder: (context, CounterModel counter, _) => Center(
              child: Text('Value: ${counter.counter}')
            )
          ),
          // floatingActionButton: FloatingActionButton(
          // child: TestIcon(),
          // onPressed: _counter.increment,
          // ),
          //用资源更新方法来设置按钮点击回调
          floatingActionButton: Consumer<CounterModel>(
            builder: (context, CounterModel counter, child) => FloatingActionButton(
              onPressed: _counter.increment,
              child: child,
            ),
            child: TestIcon(),
          )
        );

    如上代码所示,在测试的时候发现,按钮还是会不断的刷新重建

    作者回复: 你的第一行代码有主动获取build上下文:final _counter = Provider.of<CounterModel>(context);

    2019-10-28
    1
  • 二师哥
    请教一下先生,这个写的 widget 如何进行编写测试代码。按照普通的 widget 发现无法正常进行测试?

    作者回复: 参考38节的分享哈

    2019-10-22
  • 海贼王
    老师,要是把那个资源都放在main里面,会不会太多了?

    作者回复: 可以分模块分文件声明啊

    2019-10-11
  • 辉哥
    老师,实现两个类型相同对象共享,是不是依靠共享对象的两个相同类型的成员实现到

    作者回复: 可以,赞👍

    2019-09-30
  • 满大大
    我理解应该是需要夸页面共享才用provider吧,它应该是一个单利吧,正常情况下还是少用,对不对

    作者回复: 涉及到复杂的状态共享情况,无论是单页面还是跨页面,都推荐使用Provider

    2019-09-26
  • Geek_keyi
    老师,问题一是不是共享两个同样类型的不同对象,只是共享树的层次不一样,读取的时候会找最近的那个共享对象。

    作者回复: 这样可以,也可以通过封装一个大对象解决

    2019-09-26
  • 大神博士
    持久化,尤其是 Provider 中的持久化 一般怎么做

    作者回复: Provider目前还没有内置持久化的选项,不过这也不难,只要为Provider中的model提供序列化和反序列化JSON的方法,直接写到文件即可。

    2019-09-23
  • Bojack
    文档上不是说必须是不同类型的吗?

    作者回复: 是啊,所以这就是今天的问题呀

    2019-09-10
  • 亡命之徒
    老师你好,如果想修改tabbar的高度以及文字和图片的间距,必须自定义嘛,系统默认的不能修改嘛

    作者回复: 试试Tabbar的preferredSize属性

    2019-09-06
    1
  • 矮个子先生😝
    老师,provider、eventBus的用途有啥区别吗,都可以做状态的通知

    作者回复: Provider主要是用来做数据读写共享;event_bus主要是用来做数据状态通知

    2019-09-05
  • 大土豆
    老师,美团和点评的主App,flutter开始落地了吗?
    2019-09-05
收起评论
17
返回
顶部