flutter&鸿蒙next 使用 InheritedWidget 实现跨 Widget 传递状态

简介: 在 Flutter 中,状态管理至关重要。本文详细介绍了如何使用 InheritedWidget 实现跨 Widget 的状态传递。InheritedWidget 允许数据在 Widget 树中向下传递,适用于多层嵌套的场景。通过一个简单的计数器示例,展示了如何创建和使用 InheritedWidget,包括其基础概念、工作原理及代码实现。虽然 InheritedWidget 较底层,但它是许多高级状态管理解决方案的基础。

在 Flutter 中,状态管理是开发过程中一个至关重要的部分。Flutter 提供了多种方式来实现组件间的状态传递,其中一种比较底层的方式是使用 InheritedWidget。虽然 InheritedWidget 主要用于将数据传递给其子树中的小部件,但它也是许多更高级状态管理解决方案(如 Provider)的基础。本文将详细介绍如何使用 InheritedWidget 来实现跨 Widget 的状态传递。

  1. InheritedWidget 基础介绍
    InheritedWidget 是 Flutter 框架提供的一个特殊 Widget,它允许数据在 Widget 树中向下传递。当一个 Widget 需要跨越多个子 Widget 传递数据时,可以将数据保存在 InheritedWidget 中,并让它作为一个数据的容器。所有依赖于这个 InheritedWidget 的子 Widget,都能方便地获取到这些数据。

InheritedWidget 的工作原理
InheritedWidget 主要依赖 of 方法来从 Widget 树的不同位置读取数据。
InheritedWidget 会在其 child 发生变化时触发树重建。这意味着它不仅可以传递数据,还能在数据发生变化时自动更新界面。

  1. 示例代码:实现一个简单的计数器
    为了让大家更清楚地理解 InheritedWidget 的使用,我们通过实现一个简单的计数器来展示它是如何跨 Widget 传递状态的。

完整代码
import 'package:flutter/material.dart';

// 1. 创建一个 InheritedWidget,用于传递状态
class CounterInheritedWidget extends InheritedWidget {
final int counter;
final Function() increment;

CounterInheritedWidget({
Key? key,
required this.counter,
required this.increment,
required Widget child,
}) : super(key: key, child: child);

// 创建一个方法,方便其他组件获取到当前的 CounterInheritedWidget 实例
static CounterInheritedWidget of(BuildContext context) {
final result = context.dependOnInheritedWidgetOfExactType();
assert(result != null, 'No CounterInheritedWidget found in context');
return result!;
}

@override
bool updateShouldNotify(CounterInheritedWidget oldWidget) {
// 当 counter 发生变化时,通知子 Widget 进行更新
return counter != oldWidget.counter;
}
}

// 2. 创建一个使用 CounterInheritedWidget 的页面
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 获取状态数据
final counter = CounterInheritedWidget.of(context).counter;
final increment = CounterInheritedWidget.of(context).increment;

return Scaffold(
  appBar: AppBar(title: Text('InheritedWidget Counter')),
  body: Center(
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Counter Value: $counter', style: TextStyle(fontSize: 30)),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: increment,
          child: Text('Increment'),
        ),
      ],
    ),
  ),
);

}
}

// 3. 创建一个 StatefulWidget 来管理数据并使用 CounterInheritedWidget
class CounterApp extends StatefulWidget {
@override
_CounterAppState createState() => _CounterAppState();
}

class _CounterAppState extends State {
int _counter = 0;

// 增加计数
void _incrementCounter() {
setState(() {
_counter++;
});
}

@override
Widget build(BuildContext context) {
return CounterInheritedWidget(
counter: _counter,
increment: _incrementCounter,
child: CounterPage(),
);
}
}

void main() {
runApp(MaterialApp(home: CounterApp()));
}

代码解释

  1. CounterInheritedWidget 类
    CounterInheritedWidget 是继承自 InheritedWidget 的自定义类,它将计数器的值和 increment 方法封装在其中。这个 Widget 会被用来向下传递数据(在这里是计数器的值和一个函数)。

构造函数:接收 counter(计数器的值)、increment(增加计数的函数)和 child(需要显示的子组件)。
of 方法:是一个静态方法,用于从 BuildContext 获取到最近的 CounterInheritedWidget 实例。它会从当前上下文的 InheritedWidget 树中向上查找,找到最近的 CounterInheritedWidget 并返回。
updateShouldNotify 方法:当 CounterInheritedWidget 的 counter 值变化时,返回 true,通知 Widget 树的依赖此 Widget 的所有子 Widget 重新构建。

  1. CounterPage 页面
    CounterPage 是显示计数器值的页面,它通过 CounterInheritedWidget.of(context) 来获取 counter 和 increment。increment 是一个回调函数,用来更新计数器的值,counter 是计数器的当前值。

  2. CounterApp 类
    CounterApp 是一个 StatefulWidget,负责管理计数器的状态。它的 build 方法返回一个 CounterInheritedWidget,并将 _counter 和 _incrementCounter 传递给它。这个 Widget 作为根 Widget 包裹 CounterPage,让计数器的值和方法能够通过 InheritedWidget 传递给页面中的所有子 Widget。

  3. 启动应用
    main 方法启动应用,设置 CounterApp 为根 Widget。CounterApp 会初始化计数器的状态并通过 CounterInheritedWidget 传递给 CounterPage,使得子 Widget 可以访问和更新状态。

  4. 如何工作?
    CounterInheritedWidget 将 counter 和 increment 方法传递给其子树中的 CounterPage。
    CounterPage 通过 CounterInheritedWidget.of(context) 方法获取 CounterInheritedWidget 实例,从而访问 counter 和 increment。
    当按下 "Increment" 按钮时,_incrementCounter 被调用,导致 setState 被触发,_counter 的值更新。由于 CounterInheritedWidget 中的 counter 值发生变化,它会通知所有依赖它的 Widget 重新构建。最终,CounterPage 重新渲染,显示更新后的计数器值。

  5. 小结
    使用 InheritedWidget 可以让我们方便地将数据传递到 Widget 树的深层。它的优势在于:

提供了一种高效、性能优化的状态传递方式。
可以在多层嵌套的 Widget 中传递数据,避免了通过 setState 或回调的层层传递。
虽然 InheritedWidget 功能强大,但它的使用较为底层,Flutter 也提供了 Provider 等更高级的状态管理工具,可以在更复杂的应用中提供更加灵活和简洁的状态管理方案。
————————————————

                        版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/lbcyllqj/article/details/143581444

目录
相关文章
|
1月前
|
编解码 API 数据安全/隐私保护
自学HarmonyOS Next记录:实现相册访问功能
最近我决定开发一个鸿蒙App,旨在提供更好的照片管理体验。通过使用PhotoAccessHelper API,我实现了访问、显示和管理设备相册中的照片。过程中遇到了权限不足的问题,通过在config.json中添加权限声明并编写权限检查代码得以解决。此外,我还实现了分页加载和展示照片详细信息等功能,提升了用户体验。这次开发不仅让我掌握了API的使用,也深刻体会到鸿蒙系统对用户隐私和数据安全的重视。 总结这次开发,我不仅学到了技术知识,还明白了开发者保护用户数据安全的责任。未来将继续探索更多功能,欢迎关注和收藏!
177 70
自学HarmonyOS Next记录:实现相册访问功能
|
1月前
【HarmonyOS Next开发】:ListItemGroup使用
通过使用ListItemGroup和AlphabetIndexer两种类型组件,实现带标题分类和右侧导航栏的页面
128 61
【HarmonyOS Next开发】:ListItemGroup使用
|
1月前
|
安全 数据安全/隐私保护 Android开发
HarmonyOS 5.0 Next实战应用开发—‘我的家乡’【HarmonyOS Next华为公司完全自研的操作系统】
HarmonyOS NEXT是华为自研的鸿蒙操作系统的重要版本更新,标志着鸿蒙系统首次完全脱离Linux内核及安卓开放源代码项目(AOSP),仅支持鸿蒙内核和鸿蒙系统的应用。该版本引入了“和谐美学”设计理念,通过先进的物理渲染引擎还原真实世界的光影色彩,为用户带来沉浸式体验。应用图标设计融合国画理念,采用留白和实时模糊技术展现中式美学。 HarmonyOS NEXT强化了设备间的协同能力,支持无缝切换任务,如在手机、平板或电脑间继续阅读文章或编辑文件。系统注重数据安全和隐私保护,提供数据加密和隐私权限管理功能。此外,它利用分布式技术实现跨设备资源共
127 15
HarmonyOS 5.0 Next实战应用开发—‘我的家乡’【HarmonyOS Next华为公司完全自研的操作系统】
|
1月前
|
存储 JavaScript 开发工具
基于HarmonyOS 5.0(NEXT)与SpringCloud架构的跨平台应用开发与服务集成研究【实战】
本次的.HarmonyOS Next ,ArkTS语言,HarmonyOS的元服务和DevEco Studio 开发工具,为开发者提供了构建现代化、轻量化、高性能应用的便捷方式。这些技术和工具将帮助开发者更好地适应未来的智能设备和服务提供方式。
66 8
基于HarmonyOS 5.0(NEXT)与SpringCloud架构的跨平台应用开发与服务集成研究【实战】
|
1月前
|
开发者
【HarmonyOS Next开发】用户文件访问
文件所有者为登录到该终端设备的用户,包括用户私有的图片、视频、音频、文档等。 应用对用户文件的创建、访问、删除等行为,需要提前获取用户授权,或由用户操作完成。
74 10
【HarmonyOS Next开发】用户文件访问
|
1月前
|
存储 JSON 测试技术
【HarmonyOS Next开发】云开发-云数据库(二)
实现了云侧和端侧的云数据库创建、更新、修改等操作。这篇文章实现调用云函数对云数据库进行增删改查。
58 9
【HarmonyOS Next开发】云开发-云数据库(二)
|
1月前
|
1月前
|
API 容器
【HarmonyOS Next开发】Navigation使用
Navigation是路由容器组件,包括单栏(Stack)、分栏(Split)和自适应(Auto)三种显示模式。适用于模块内和跨模块的路由切换。 在页面跳转时,应该使用页面路由router,在页面内的页面跳转时,建议使用Navigation达到更好的转场动效场景。
129 8
【HarmonyOS Next开发】Navigation使用
|
1月前
|
Dart 前端开发 IDE
鸿蒙Flutter实战:14-现有Flutter 项目支持鸿蒙 II
本文介绍了如何将现有 Flutter 项目适配鸿蒙系统,详细步骤包括安装 FVM、使用 FVM 安装 Flutter SDK、搭建开发环境、创建项目架构和壳工程等。
215 4
鸿蒙Flutter实战:14-现有Flutter 项目支持鸿蒙 II
|
1月前
|
存储 IDE JavaScript
【HarmonyOS Next开发】端云一体化初始化项目
端云一体化开发是HarmonyOS对云端开发的支持、实现端云联动。云开发服务提供了云函数、云数据库、云存储等服务,可以使开发者专注于应用的业务逻辑开发,无需关注基础设施,例如:服务器、操作系统等问题。
70 6
【HarmonyOS Next开发】端云一体化初始化项目