Flutter基础学习5_功能型组件

194 阅读3分钟

功能型widget组件: 不会影响UI布局及外观

一、 导航返回拦截 (willPopScope)

、、、 const WillPopScope({ ... @required WillPopCallback onWillPop, @required Widget child }) 、、、

  • onWillPop是一个回调函数,当用户点击返回按钮时被调用(包括导航返回按钮及Android物理返回按钮)。该回调需要返回一个Future对象,如果返回的Future最终值为false时,则当前路由不出栈(不会返回);最终值为true时,当前路由出栈退出。我们需要提供这个回调来决定是否退出

二、 数据共享 (inheritedWidget)

  1. InheritedWidget 提供了一种数据在widget 树中 从上到下传递、 共享的方式;eg: 在应用的根widget中通过 InheritedWidget 共享了一个数据 在别的任意子widget中都可以获取该共享的数据 ;应用: 共享主题Theme 和语言 Loacle
  2. didChangeDependencies 、、、 //定义一个便捷方法,方便子树中的widget获取共享数据
    static ShareDataWidget of(BuildContext context) { return context.inheritFromWidgetOfExactType(ShareDataWidget); // return context.ancestorInheritedElementForWidgetOfExactType(ShareDataWidget).widget; } 、、、
  3. inheritFromWidgetOfExactType 和ancestorInheritedElementForWidgetOfExactType的区别

、、、 @override InheritedElement ancestorInheritedElementForWidgetOfExactType(Type targetType) { final InheritedElement ancestor = _inheritedWidgets == null ? null : _inheritedWidgets[targetType]; return ancestor; } @override InheritedWidget inheritFromWidgetOfExactType(Type targetType, { Object aspect }) { final InheritedElement ancestor = _inheritedWidgets == null ? null : _inheritedWidgets[targetType]; //多出的部分 if (ancestor != null) { assert(ancestor is InheritedElement); return inheritFromElement(ancestor, aspect: aspect); } _hadUnsatisfiedDependencies = true; return null; } 、、、 从源码可以看出 : inheritFromWidgetOfExactType() 比 ancestorInheritedElementForWidgetOfExactType()多调了inheritFromElement方法 调用inheritFromWidgetOfExactType() 和 ancestorInheritedElementForWidgetOfExactType()的区别就是前者会注册依赖关系,而后者不会,所以在调用inheritFromWidgetOfExactType()时,InheritedWidget和依赖它的子孙组件关系便完成了注册,之后当InheritedWidget发生变化时,就会更新依赖它的子孙组件,也就是会调这些子孙组件的didChangeDependencies()方法和build()方法。而当调用的是 ancestorInheritedElementForWidgetOfExactType()时,由于没有注册依赖关系,所以之后当InheritedWidget发生变化时,就不会更新相应的子孙Widget。

三、 跨组件状态共享 ( provider)

  1. 状态管理:如果状态是组件私有的,则应该由组件自己管理;如果状态要跨组件共享,则该状态应该由各个组件共同的父元素来管理。
  2. 虽然上面的例子比较简单,但它却将Provider的原理和流程体现的很清楚,图7-3是Provider的原理图:
  3. Model变化后会自动通知ChangeNotifierProvider(订阅者),ChangeNotifierProvider内部会重新构建InheritedWidget,而依赖该InheritedWidget的子孙Widget就会更新。
  4. 我们可以发现使用Provider,将会带来如下收益:
  5. 我们的业务代码更关注数据了,只要更新Model,则UI会自动更新,而不用在状态改变后再去手动调用setState()来显式更新页面。
  6. 数据改变的消息传递被屏蔽了,我们无需手动去处理状态改变事件的发布和订阅了,这一切都被封装在Provider中了。这真的很棒,帮我们省掉了大量的工作!
  7. 在大型复杂应用中,尤其是需要全局共享的状态非常多时,使用Provider将会大大简化我们的代码逻辑,降低出错的概率,提高开发效率。

四、 颜色和主题

  1. Color(0xffdc380d); //如果颜色固定可以直接使用整数值 Color(int.parse(c,radix:16)).withAlpha(255) //通过方法将Alpha设置为FF
  2. color: color.computeLuminance() < 0.5 ? Colors.white : Colors.black,//根据背景色亮度来确定Title颜色

五、 异步UI更新 FutureBuilder 将来、 streamBuilder

  1. FutureBuiler: 依赖future 的状态来构建自身 构造函数: 、、、 FutureBuilder({ this.future, // FutureBuilder依赖的Future,通常是一个异步耗时任务 this.initialData, // 初始数据,用户设置默认数据。 @required this.builder, //Widget构建器;该构建器会在Future执行的不同阶段被多次调用,构建器签名如下: Function (BuildContext context, AsyncSnapshot snapshot) }) 、、、

  2. StreamBuilder: 在Dart中 Stream 用于接收 异步事件数据 , 和future不同的是, 可以接收多个异步操作的结果 、、、 、、、 StreamBuilder({ Key key, this.initialData, Stream stream, @required this.builder, }) 、、、

六、 对话框 AlertDialog