flutter InheritedWidget使用方法总结
引言
InheritedWidget,flutter中非常重要的一个功能组件。比如我们在应用的根 widget 中通过InheritedWidget共享了一个数据,那么我们便可以在任意子 widget 中来获取该共享的数据。
didChangeDependencies
说到 InheritedWidget ,我们不得不聊聊 state 对象中的 didChangeDependencies
方法。当子控件依赖使用了父控件中的 InheritedWidget,比如主题、locale(语言)等发生变化时,依赖其的子 widget 的didChangeDependencies
方法将会被调用。
一般来说,子 widget 很少会重写此方法,因为在依赖改变后 framework 也都会调用build()方法。但是,如果你需要在依赖改变后执行一些昂贵的操作,比如网络请求,这时最好的方式就是在此方法中执行,这样可以避免每次build()都执行这些昂贵操作。
重点: 如子控件build 方法中没有使用 InheritedShareWidget 的数据,那么它的didChangeDependencies
将不会被调用
如何使用?
我们简单用一个 count 自增的例子来记录 InheritedWidget 的使用:
- 新建 InheritedShareWidget 继承 InheritedWidget 作为共享数据源,以其为父节点提供子节点数据
import 'package:flutter/material.dart'; class InheritedShareWidget extends InheritedWidget { //用于共享的数据 final int data; InheritedShareWidget({this.data, Widget child}) : super(child: child); //定义便捷方法,方便子控件获取共享数据 static InheritedShareWidget of(BuildContext context) { ///当子控件依赖使用了我们的数据源时,数据变动会触发子控件中的 didChangeDependencies 方法 return context.dependOnInheritedWidgetOfExactType<InheritedShareWidget>(); ///(前提:子控件使用了数据源)子控件中的 didChangeDependencies 方法不会被触发 // return context.getElementForInheritedWidgetOfExactType<InheritedShareWidget>().widget; } @override bool updateShouldNotify(covariant InheritedShareWidget oldWidget) { //返回true时,才会通知子控件 return oldWidget.data != this.data; } }
注意:updateShouldNotify
方法中,通知指的是通知子控件的didChangeDependencies
方法,前提是子控件使用dependOnInheritedWidgetOfExactType
的方式获取共享数据。
- 子节点中如何获取共享数据?
class TestShareChildWidget extends StatefulWidget { const TestShareChildWidget({Key key}) : super(key: key); @override _TestShareChildWidgetState createState() => _TestShareChildWidgetState(); } class _TestShareChildWidgetState extends State<TestShareChildWidget> { @override void didChangeDependencies() { ///如build 方法中没有使用 InheritedShareWidget 的数据,那么它的didChangeDependencies()将不会被调用 super.didChangeDependencies(); print("enter didChangeDependencies"); } @override Widget build(BuildContext context) { print("enter child build"); //获取Inherited的共享数据: final data = InheritedShareWidget.of(context).data.toString(); return Text(data); } }
- 两者通过父子嵌套的关系联系在一起:
class _TestInheritedWidgetState extends State<TestInheritedWidget> { int count = 0; @override Widget build(BuildContext context) { return Center( child: InheritedShareWidget( data: count, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TestShareChildWidget(), RaisedButton( child: Text('add'), onPressed: () { setState(() { ++count; }); }) ], ), ), ); } }
大家注意到,demo中操作++count
时,使用了setState
手动触发控件进行刷新。
结论
InheritedWidget
只提供我们共享数据的能力,以及控制是否在 build 前触发didChangeDependencies
的能力。不会主动触发build
方法,如果build
没被触发,那么didChangeDependencies
也不会被触发。
号外扩展
InheritedWidget 数据共享能力不会受到 Navigator push
新页面的影响,与原生不一样,flutter的页面跳转不是管理一个堆栈,Navigator
本质上是使用 overlay
管理一个 stack
widget,因此 InheritedWidget
基于父子关系管理的数据共享条件没有被打破
以上就是flutter InheritedWidget使用方法总结的详细内容,更多关于flutter InheritedWidget使用的资料请关注脚本之家其它相关文章!
相关文章
Android 解决dialog弹出时无法捕捉Activity的back事件问题
这篇文章主要介绍了Android 解决dialog弹出时无法捕捉Activity的back事件问题的相关资料,需要的朋友可以参考下2016-11-11Android GestureDetector用户手势检测实例讲解
这篇文章主要为大家详细介绍了Android GestureDetector用户手势检测实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-03-03python gstreamer实现视频快进/快退/循环播放功能
这篇文章主要介绍了python gstreamer 实现视频快进/快退/循环播放功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下2020-03-03Hook实现Android 微信、陌陌 、探探位置模拟(附源码下载)
这篇文章主要介绍了Hook实现Android 微信、陌陌 、探探位置模拟(附源码下载)的相关资料,需要的朋友可以参考下2017-03-03Android编程实现activity dialog透明背景的方法
这篇文章主要介绍了Android编程实现activity dialog透明背景的方法,涉及Activity相关属性设置及配置文件操作技巧,需要的朋友可以参考下2017-07-07Android编程实现WebView全屏播放的方法(附源码)
这篇文章主要介绍了Android编程实现WebView全屏播放的方法,结合实例形式较为详细的分析了Android实现WebView全屏播放的布局与功能相关技巧,需要的朋友可以参考下2015-11-11
最新评论