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 中StringBuffer 和StringBuilder常用方法
这篇文章主要介绍了Android 中StringBuffer 和StringBuilder的常用方法及区别介绍,需要的朋友可以参考下2017-02-02使用RoundedBitmapDrawable生成圆角图片的方法
由于RoundedBitmapDrawable类没有直接提供生成圆形图片的方法,所以生成圆形图片首先需要对原始图片进行裁剪,将图片裁剪成正方形,最后再生成圆形图片,具体实现方法,可以参考下本文2016-09-09Android在view.requestFocus(0)返回false的解决办法
这篇文章主要介绍了Android在view.requestFocus(0)返回false的解决办法,非常不错,具有参考借鉴价值,需要的朋友参考下2016-08-08
最新评论