Flutter ValueNotifier 异步通信、ValueListenableBuilder异步更新数据

Flutter数据更新实践
本文介绍Flutter中页面数据更新的方法,包括使用Navigator回调刷新页面数据,ValueNotifier与ValueListenableBuilder组合实现局部数据更新,以及自定义ValueNotifier进行更精细的数据控制。

题记
—— 执剑天涯,从你的点滴积累开始,所及之处,必精益求精。


Flutter是谷歌推出的最新的移动开发框架。

【x1】微信公众号的每日提醒 随时随记 每日积累 随心而过

【x2】各种系列的视频教程 免费开源 关注 你不会迷路

【x3】系列文章 百万 Demo 随时 复制粘贴 使用


在 Flutter 中可用于异步通信的方案有如下:

本文章讲述使用 Navigator 更新页面 A 的数据、ValueListenableBuilder 的基本使用、自定义 ValueNotifier 进行局部数据的更新

1 前言

在实际项目开发中,有一种业务需求就是 页面A 进入页面B ,在页面B中数据发生改变后需要更新页面A 中的内容,其实第一种方案可以考虑使用 then函数回调,如下代码清单1-1所示,在页面A中以动态路由的方式打开页面TestBPage,并实现 Navigator 的then 函数,then 函数会在 TestBPage 页面关闭时回调。

///代码清单 1-1 
 void openPageFunction(BuildContext context) {
   ///以动态路由的方式打开
   Navigator.of(context).push(
     MaterialPageRoute(
       builder: (BuildContext context) {
         return TestBPage();
       },
     ),
     ///页面 TestBPage 关闭后会回调 then 函数
     ///其中参数 value 为回传的参数
   ).then((value) {
     if (value != null) {
       setState(() {
         _message = value;
       });
     }
   });
 }

当在页面 TestBPage 关闭时,可以主动回传参数,如下代码 清单 1-2 所示:

 ///代码 清单 1-2
 OutlineButton buildOutlineButton(BuildContext context) {
   return OutlineButton(
     child: Text("返回页面 A "),
     onPressed: () {
       String result = "345";
       Navigator.of(context).pop(result);
     },
   );
 }

这一种方法的一个实际应用场所如一个订单的详情页面,打开下一个页面进行操作后,再返回当前页面后需要刷新页面的数据,此种场景就可使用这种方法。

使用 then 函数达成的数据传递或者说页面刷新,对于用户来讲是可见的,就是有时数据刷新的慢点,用户是可以有感觉的,使用ValueNotifier可以达到无感刷新。

2 ValueNotifier 的基本使用

ValueNotifier 需要结合组件 ValueListenableBuilder 来使用。

/// 第一步 定义 ValueNotifier  这里传递的数据类型为 String
ValueNotifier<String> _testValueNotifier = ValueNotifier<String>('');
///第二步定义 数据变化后监听的 Widget
Widget buildValueListenableBuilder() {
  return ValueListenableBuilder(
    ///数据发生变化时回调
    builder: (context, value, child) {
      return Text(value);
    },
    ///监听的数据
    valueListenable: _testValueNotifier,
    child: Text(
      '未登录',
      style: TextStyle(color: Colors.red),
    ),
  );
}
///第三步就是数据变化后
 void testFunction() {
   ///赋值更新
   _testValueNotifier.value = '传递的测试数据';
 }

在上述代码片段中,传递更新的数据是一个String,当然在业务开发场景中,会有更多自定义的 Model,直接替换上述的String就可以。

3 自定义 ValueNotifier 局部更新

如有一个用户数据类型的Model定义如下 :

///实际中变量可能足够的多
class UserInfo {
  String name;
  int age ;
}

我们期望只修改其中的如 age 一个属性的值,此时就需要自定 ValueNotifier ,如下代码清单 1-3 所示:

///代码清单 1-3 
///自定义 ValueNotifier
/// UserInfo 为数据类型
class UserNotifier extends ValueNotifier<UserInfo> {

  UserNotifier(UserInfo userInfo): super(userInfo);

  void setName(String name) {
    ///赋值 这里需要注意的是 如果没有给 ValueNotifier 赋值 UserInfo 对象时
    /// value 会出现空指针异常
    value.name =name;
    ///通知更新
    notifyListeners();
  }

}

然后在使用的时候,创建 UserNotifier 如下 :

///第一步
UserNotifier _testUserNotifier = UserNotifier(UserInfo(name: "", age: 0));

构建 ValueListenableBuilder

 ///第二步 定义
 Widget buildUserListenableBuilder() {
   return ValueListenableBuilder(
     ///数据发生变化时回调
     builder: (context, value, child) {
       return Text("姓名是:${value.name}  年龄是: ${value.age}");
     },
     ///监听的数据
     valueListenable: _testUserNotifier,
   );
 }

当数据变化时进行更新操作

 void testUserFunction() {
   _testUserNotifier.setName("李四");
 }

这种应用场景如实际项目开发中的修改用户数据,只修改了其中的一个属性数据,可以考虑使用这种方法,当然有很多情况大家是不考虑这种细节的,直接全部更新的,但是所有的细节综合起来,就解决了 你的应用为什么体验总是差点的问题。


完毕 当然必须是有源码的 本文章源码在这里

当然以小编的性格,肯定是要有视频录制的,目前正在录制中,你可以关注一下 西瓜视频 — 早起的年轻人 随后会上传

<think>首先,用户的问题是关于在Flutter中使用ValueNotifier实现异步通信的机制或方法。用户引用了三个引用,我需要参考这些内容来回答。 回顾引用内容: - 引用[1]:解释了ValueNotifier的基本使用,包括定义ValueNotifier、使用ValueListenableBuilder构建UI,以及如何更新值。 - 引用[2]:讨论了自定义ValueNotifier来处理复杂对象,如只更新对象的一个属性。 - 引用[3]:提到了GetX状态管理,但似乎不直接相关,因为用户问题聚焦于ValueNotifier。 用户的核心问题是:如何在Flutter中使用ValueNotifier实现异步通信。 理解异步通信:在Flutter中,异步操作如网络请求、文件读写等,可能需要更新UI。ValueNotifier是一种轻量级的状态管理工具,用于通知监听器值的变化。它可以与异步操作结合使用。 我的回答需要: - 结构清晰:逐步解释如何实现。 - 使用中文:因为系统指令要求中文回答。 - 正确格式:行内数学表达式用$...$,独立公式用$$...$$,但这个问题可能不涉及数学表达式,所以可能不需要。 - 生成相关问题:在最后添加相关问题。 - 添加引用标识:在回答中引用段落时添加[^1]等,但用户提供的引用是示例,我需要基于它们来引用。 关键点基于引用: - ValueNotifier用于存储值并通知变化。 - 结合ValueListenableBuilder更新UI。 - 对于异步操作,可以在异步函数中更新ValueNotifier的值。 实现异步通信的步骤: 1. 定义ValueNotifier:存储数据。 2. 在UI中使用ValueListenableBuilder:监听变化并重建UI。 3. 在异步函数中更新ValueNotifier:例如,在Future.then或async/await中设置新值。 例如: - 假设有一个异步函数获取数据(如API调用)。 - 在函数完成后,设置ValueNotifier.value为新数据。 - 这会触发ValueListenableBuilder重建UI。 自定义ValueNotifier(如引用[2])可以用于更复杂的场景,比如只更新对象的部分属性。 回答结构: 1. 介绍ValueNotifier异步通信。 2. 逐步解释实现方法。 3. 提供代码示例。 4. 添加引用标识。 5. 最后生成相关问题。 生成相关问题: - 基于主题,如ValueNotifier的局限性、优化方法、与其他状态管理的比较等。 确保回答真实可靠:基于Flutter官方文档和最佳实践。 最终回答大纲: - 开头:解释ValueNotifier如何用于异步通信。 - 步骤1:定义ValueNotifier。 - 步骤2:创建异步函数更新值。 - 步骤3:使用ValueListenableBuilder构建UI。 - 代码示例。 - 结尾:总结。 - 相关问题。</think>### Flutter 中使用 ValueNotifier 实现异步通信的方法 在 Flutter 中,`ValueNotifier` 是一种轻量级的状态管理工具,用于存储值并通知监听器数据变化。结合异步操作(如网络请求、文件读写),它可以实现高效的异步通信机制。核心原理是:在异步函数完成时更新 `ValueNotifier` 的值,触发 UI 自动重建。以下是详细实现步骤,基于引用内容优化。 #### 步骤 1: 定义 ValueNotifier 定义 `ValueNotifier` 存储需要异步更新数据。支持基本类型或自定义对象。 - **基本类型示例**(如字符串): ```dart // 定义 ValueNotifier,初始值为空字符串 ValueNotifier<String> _asyncDataNotifier = ValueNotifier<String>(''); ``` - **自定义对象示例**(如从 API 获取的数据): 引用[2] 建议自定义 `ValueNotifier` 以处理复杂更新: ```dart class UserData { String name; int age; UserData(this.name, this.age); } // 自定义 ValueNotifier,支持部分属性更新 class UserNotifier extends ValueNotifier<UserData> { UserNotifier(UserData data) : super(data); // 异步更新方法 Future<void> updateNameAsync(String newName) async { await Future.delayed(Duration(seconds: 1)); // 模拟异步延迟 value.name = newName; // 更新属性 notifyListeners(); // 通知监听器 } } // 初始化 final userNotifier = UserNotifier(UserData('Alice', 30)); ``` #### 步骤 2: 实现异步函数更新值 在异步操作(如 `Future`)中更新 `ValueNotifier.value`,触发通知。 - **示例:模拟 API 请求**: ```dart Future<void> fetchData() async { try { // 模拟异步网络请求 final response = await http.get(Uri.parse('https://api.example.com/data')); if (response.statusCode == 200) { _asyncDataNotifier.value = response.body; // 更新值,自动通知监听器 } } catch (e) { _asyncDataNotifier.value = 'Error: $e'; // 错误处理 } } ``` 关键点:异步操作完成后,直接赋值 `value` 属性(如 `_asyncDataNotifier.value = newData`),这会自动调用 `notifyListeners()`[^1]。 #### 步骤 3: 使用 ValueListenableBuilder 构建响应式 UI 通过 `ValueListenableBuilder` 监听 `ValueNotifier` 变化,并重建 UI。 - **基础用法**(引用[1]): ```dart Widget buildAsyncUI() { return ValueListenableBuilder<String>( valueListenable: _asyncDataNotifier, // 绑定 ValueNotifier builder: (context, value, child) { // value 是 _asyncDataNotifier 的当前值 return Text(value.isEmpty ? 'Loading...' : value); }, child: CircularProgressIndicator(), // 可选:初始加载指示器 ); } ``` - **自定义对象更新**: ```dart ValueListenableBuilder<UserData>( valueListenable: userNotifier, builder: (context, user, child) { return Text('Name: ${user.name}, Age: ${user.age}'); }, ); ``` #### 完整代码示例 以下是一个简单应用,模拟异步数据加载: ```dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { final ValueNotifier<String> _dataNotifier = ValueNotifier<String>(''); Future<void> _loadData() async { _dataNotifier.value = 'Loading...'; // 更新加载状态 await Future.delayed(Duration(seconds: 2)); // 模拟延迟 _dataNotifier.value = 'Data loaded!'; // 更新最终数据 } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('ValueNotifier Async Demo')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ValueListenableBuilder<String>( valueListenable: _dataNotifier, builder: (context, value, child) { return Text(value, style: TextStyle(fontSize: 20)); }, ), ElevatedButton( onPressed: _loadData, // 触发异步函数 child: Text('Load Data'), ), ], ), ), ), ); } } ``` #### 优势与注意事项 - **优势**: - 轻量高效:适合局部状态管理,避免过度依赖大型状态库[^1]。 - 自动重建:`ValueListenableBuilder` 仅在值变化时重建 UI,性能优化。 - **注意事项**: - 内存管理:在页面销毁时调用 `dispose()` 释放资源,防止内存泄漏。 - 复杂场景:对于跨组件通信,可结合 `Provider` 或 `GetX`(引用[3])扩展。 通过以上方法,`ValueNotifier` 能有效处理异步通信,确保 UI 与数据同步更新[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早起的年轻人

创作源于分享

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值