【Flutter】Flutter局部刷新的几种方式

news/2024/9/22 23:56:30/

前言

在Flutter开发中,我们会根据一些状态的值来改变UI样式,setState也是我们常用的状态刷新方式;但是当我们的页面布局比较复杂的时候,我们再用setState的时候,整个页面就会重绘,比较影响APP的性能,这种场景我们就可以只更新局部的组件。

局部更新

我们可以只更新界面的某一个Widget,不需要更新全部的界面,提高加载速度和节约性能的开销,如果是列表,还能够提交流程度,等等。。。

1. setState() 方法

setState是Flutter最简单也是最直接方式了,我们可以把一下复杂的UI拆分封装成不同的Widget,然后在封转的Widget里面进行局部刷新。

示例:

/// 复杂的UI滑竿组件封装成一个单独的Widget
/// 滑竿Widget _customSlider() {double sliderWidth = kXTScreenUtil.screenWidth - 16 * 2;return XTModularNodeSlisder(key: _slisderStateKey,width: sliderWidth,bubbleUnit: "%",isShowBubble: true,alwaysDisplayBubble: true,itemData: _itemData!,onTapEnd: (value, ltvValue){_sliderValueChanged(ltvValue);_updateErrorTips();},);}

2. ValueNotifier 和 ValueListenableBuilder

ValueNotifier 是 Flutter 提供的一种轻量级状态管理工具,可以用于监听特定值的变化并刷新相关 UI。结合 ValueListenableBuilder,可以在特定值改变时触发局部刷新。

示例:

class ZFJWidget extends StatelessWidget {// vnfinal ValueNotifier<int> counter = ValueNotifier<int>(0);@overrideWidget build(BuildContext context) {return Column(children: [ValueListenableBuilder<int>(valueListenable: counter,builder: (context, value, child) {// 仅刷新这个 Text widgetreturn Text('$value');},),ElevatedButton(onPressed: () {// 更新 ValueNotifier,局部刷新counter.value++;},child: Text('Increment'),),],);}
}

3. StreamBuilder

如果需要基于异步数据流进行刷新,StreamBuilder 是一个非常合适的工具。它会监听 Stream,当数据流更新时,局部的 widget 也会自动更新。
当 Stream 中的数据发生变化时,StreamBuilder 会重新构建相关的部分。

class ZFJWidget extends StatelessWidget {// final Stream<int> counterStream = Stream<int>.periodic(Duration(seconds: 1), (x) => x);@overrideWidget build(BuildContext context) {return StreamBuilder<int>(stream: counterStream,builder: (context, snapshot) {if (snapshot.hasData) {return Text('Count: ${snapshot.data}');} else {return CircularProgressIndicator();}},);}
}

4. InheritedWidget

InheritedWidget 是一种提供数据共享的方式,可以在 widget 树中共享状态,并通过该 widget 实现局部刷新。
比如下面的代码,当 Counter 中的数据改变时,它的子 widget 树会触发局部刷新。

示例:

class Counter extends InheritedWidget {final int count;Counter({Key? key, required this.count, required Widget child}) : super(key: key, child: child);static Counter of(BuildContext context) {return context.dependOnInheritedWidgetOfExactType<Counter>()!;}@overridebool updateShouldNotify(Counter oldWidget) {return oldWidget.count != count;}
}class ZFJWidget extends StatelessWidget {@overrideWidget build(BuildContext context) {return Counter(count: 10,child: Column(children: [_ChildWidget(),],),);}
}class _ChildWidget extends StatelessWidget {@overrideWidget build(BuildContext context) {final count = Counter.of(context).count;return Text('Count: $count');}
}

5. ChangeNotifier + Consumer(Provider)

通过 ChangeNotifier 和 Provider 实现状态管理与局部刷新。

class Counter extends ChangeNotifier {int _count = 0;int get count => _count;void increment() {_count++;notifyListeners();}
}class CounterProviderWidget extends StatelessWidget {@overrideWidget build(BuildContext context) {return ChangeNotifierProvider(create: (context) => Counter(),child: Column(children: [Consumer<Counter>(builder: (context, counter, child) {return Text('Counter: ${counter.count}');},),ElevatedButton(onPressed: () {Provider.of<Counter>(context, listen: false).increment();},child: Text('Increment'),),],),);}
}

6.RepaintBoundary

通过 RepaintBoundary 控制子 widget 的重绘范围,从而实现性能优化的局部刷新。

class RepaintBoundaryExample extends StatelessWidget {@overrideWidget build(BuildContext context) {return RepaintBoundary(child: Text('This part will be repainted independently'),);}
}

总结

上述几种方式可以根据不同的需求场景来选择。setState 是最基础的局部刷新,ValueNotifier 和 ChangeNotifier 等更适合状态管理场景,而 RepaintBoundary 则更注重性能优化。


http://www.ppmy.cn/news/1529063.html

相关文章

Redis安装 ▎Redis详细知识点

前言: Redis是一个开源的内存数据结构存储&#xff0c;支持丰富的数据类型&#xff0c;如字符串、哈希、列表、集合和有序集合,作为一个键值对数据库&#xff0c;Redis能提供毫秒级的响应时间&#xff0c;适合高并发应用场景。它还支持持久化&#xff0c;将内存数据定期保存到…

5.内容创作的未来:ChatGPT如何辅助写作(5/10)

引言 在信息爆炸的时代&#xff0c;内容创作已成为连接品牌与受众、传递信息与知识、以及塑造文化与观念的重要手段。随着数字媒体的兴起&#xff0c;内容创作的需求日益增长&#xff0c;对创作者的写作速度和质量提出了更高的要求。人工智能&#xff08;AI&#xff09;技术的…

家政小程序开发/源码/上门维修/上门保洁服务平台

开发一个家政小程序是一个涉及多方面技术的项目&#xff0c;主要目标是为用户提供便捷的家政服务预约、查询和管理功能。以下是一个简要的开发流程和一些关键点&#xff0c;帮助你开始这个项目&#xff1a; 1.需求分析 用户调研&#xff1a;了解目标用户群体&#xff08;如家庭…

图像分割基本知识

计算机视觉和图像处理 Tensorflow入门深度神经网络图像分类目标检测图像分割 图像分割 一、目标分割1.1 图像分割的定义1.2 任务类型1.2.1 任务描述1.2.2 任务类型 二、语义分割2.1 FCN网络2.1.1网络结构 2.2 Unet网络 三、UNet案例3.1 数据集获取3.1.1 设置相关信息3.1.2 图像…

Unity自我实现响应式属性

其实只是写着玩,响应式编程建议使用UniRx插件(一套成熟的响应式编程解决方案),我写的主要是借鉴一下这个思想,实现的也不够优雅,不过逻辑也算严密可以正常使用.你可以查看我写的理解响应式属性的思想. 借鉴UniRx的ReactiveProperty类,且UniRx不仅有响应式属性. using System; …

【笔记】第三节 组织与性能

3.1 基本成分 3.2 微观组织特征 0.6-0.8C%碳素钢的组织为珠光体和少量的铁素体。 如何把组织和性能联系起来&#xff1f;德国克虏伯公司的研究——珠光体片间距与渗碳体片层厚度成比例&#xff1a; t s 0 ( ρ 15 ( C % ) − 1 ) ts_0(\frac{\rho}{15(C\%)}-1) ts0​(15(C%)…

分布式计算技术是什么?在数据集成值得作用?

数据是现代科技技术的基础&#xff0c;面对爆炸性数据的增长&#xff0c;要求计算能力要求更高、数据整合和处理更有效&#xff0c;如何应对数据集成带来的挑战&#xff1f;本文将探讨分布式计算技术在数据集成中的优化作用。 一 分布式计算技术。 定义&#xff1a;分布式计算…

[数据结构]无头单向非循环链表的实现与应用

文章目录 一、引言二、线性表的基本概念1、线性表是什么2、链表与顺序表的区别3、无头单向非循环链表 三、无头单向非循环链表的实现1、结构体定义2、初始化3、销毁4、显示5、增删查改 四、分析无头单向非循环链表1、存储方式2、优点3、缺点 五、总结1、练习题2、源代码 一、引…