網站首頁 編程語言 正文
引言
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
基于父子關系管理的數據共享條件沒有被打破
原文鏈接:https://juejin.cn/post/7007676491605475358
相關推薦
- 2021-12-08 el-cascader 級聯選擇器回顯數據 (帶有子級children)
- 2022-08-18 C#開發Windows?UWP系列之對話框MessageDialog和ContentDialog_C
- 2023-01-18 Go語言讀取YAML?配置文件的兩種方式分享_Golang
- 2023-03-02 docker-compose安裝RabbitMQ及插件操作步驟_docker
- 2022-07-02 Python零錢兌換的實現代碼_python
- 2022-03-21 Prometheus容器化部署的實踐方案_docker
- 2022-08-30 Kotlin object的用法和內存泄漏研究
- 2022-05-03 C#設計模式之簡單工廠模式_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支