题记

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


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

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

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

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


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



Provider (​​ Provider 异步通信、Provider状态管理​​)



ValueNotifier ​​点击查看详情​



Stream: ​​StreamController的使用详情​​ | ​​StreamBuilder组件的结合使用​​ | ​​StreamBuilder 实现的倒计时进度圆圈​



EventBus (不考虑使用)



Bloc ​​BLoC 异步通信、BlocBuilder的基本使用、BlocProvider的初探




本文章讲述使用 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("李四");
}

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


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

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