当前位置: 首页 > news >正文

flutter开发实战-ValueListenableBuilder实现局部刷新功能

flutter开发实战-ValueListenableBuilder实现局部刷新功能

在创建的新工程中,点击按钮更新counter后,通过setState可以出发本类的build方法进行更新。当我们只需要更新一小部分控件的时候,通过setState就不太合适了,这就需要进行局部更新,可以通过provider等状态管理库来实现。当然flutter为我们提供了ValueListenableBuilder来实现局部控件的刷新。

一、ValueListenableBuilder

ValueListenableBuilder的属性如下

const ValueListenableBuilder({super.key,required this.valueListenable,required this.builder,this.child,}) : assert(valueListenable != null),assert(builder != null);
  • ValueListenable继承自Listenable,是一个可监听对象。
  • builder是一个typedef
    typedef ValueWidgetBuilder = Widget Function(BuildContext context, T value, Widget? child);
  • child,可选,可为空

查看ValueListenableBuilder类的实现可以看到

class _ValueListenableBuilderState<T> extends State<ValueListenableBuilder<T>> {late T value;@overridevoid initState() {super.initState();value = widget.valueListenable.value;widget.valueListenable.addListener(_valueChanged);}@overridevoid didUpdateWidget(ValueListenableBuilder<T> oldWidget) {super.didUpdateWidget(oldWidget);if (oldWidget.valueListenable != widget.valueListenable) {oldWidget.valueListenable.removeListener(_valueChanged);value = widget.valueListenable.value;widget.valueListenable.addListener(_valueChanged);}}@overridevoid dispose() {widget.valueListenable.removeListener(_valueChanged);super.dispose();}void _valueChanged() {setState(() { value = widget.valueListenable.value; });}@overrideWidget build(BuildContext context) {return widget.builder(context, value, widget.child);}
}

在initState中对传入的可监听对象进行监听,执行_valueChanged方法,_valueChanged执行了setState来触发当前状态的刷新。我们知道setState会执行build方法,触发执行build方法,最总触发widget.builder回调,这样就实现了局部刷新。

child的作用也是非常重要的,我们将Widget放到child中,在执行builder时,会直接使用child,将不会再构建一遍child。

二、ValueListenableBuilder实现局部刷新示例

下面使用ValueListenableBuilder来实现一个局部刷新的示例。示例中,在界面中,有一个显示按钮与隐藏按钮控制修改isShowNotifier的value。通过ValueListenableBuilder的builder中来判断需要显示的内容。
示例代码如下

import 'package:flutter/material.dart';class ValueListenablePage extends StatefulWidget {const ValueListenablePage({super.key});@overrideState<ValueListenablePage> createState() => _ValueListenablePageState();
}class _ValueListenablePageState extends State<ValueListenablePage> {final isShowNotifier = ValueNotifier<bool>(false);@overridevoid initState() {// TODO: implement initStatesuper.initState();}void show() {isShowNotifier.value = true;}void hide() {isShowNotifier.value = false;}@overridevoid dispose() {// TODO: implement disposeisShowNotifier.dispose();super.dispose();}@overrideWidget build(BuildContext context) {Size screenSize = MediaQuery.of(context).size;return Scaffold(appBar: AppBar(title: const Text('ValueListenablePage'),),body: Container(width: screenSize.width,height: screenSize.height,child: Stack(alignment: Alignment.center,children: [Positioned(top: 50,child: buildValueListenable(context),),Positioned(top: 200,child: buildButton(context),),],),),);}Widget buildHide(BuildContext context) {return Container(color: Colors.green,padding: EdgeInsets.symmetric(vertical: 20, horizontal: 50),child: Text("当前隐藏",textAlign: TextAlign.center,overflow: TextOverflow.ellipsis,softWrap: true,style: TextStyle(fontSize: 16,fontWeight: FontWeight.w600,fontStyle: FontStyle.italic,color: Colors.white,decoration: TextDecoration.none,),),);}Widget buildValueListenable(BuildContext context) {return ValueListenableBuilder(valueListenable: isShowNotifier,builder: (BuildContext aContext, bool isShow, Widget? child) {if (isShow) {return child ?? buildHide(context);} else {return buildHide(context);}},child: Container(color: Colors.blueGrey,padding: EdgeInsets.symmetric(vertical: 50, horizontal: 50),child: Text("ValueListenableBuilder Child",textAlign: TextAlign.center,overflow: TextOverflow.ellipsis,softWrap: true,style: TextStyle(fontSize: 16,fontWeight: FontWeight.w600,fontStyle: FontStyle.italic,color: Colors.white,decoration: TextDecoration.none,),),),);}Widget buildButton(BuildContext context) {return Container(width: 300,height: 220,color: Colors.deepOrange,child: Column(mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,children: [TextButton(onPressed: () {show();},child: Container(height: 50,width: 200,color: Colors.lightBlue,alignment: Alignment.center,child: Text('点击显示',style: TextStyle(fontSize: 14,color: Colors.white,),),),),TextButton(onPressed: () {hide();},child: Container(height: 50,width: 200,color: Colors.lightBlue,alignment: Alignment.center,child: Text('点击隐藏',style: TextStyle(fontSize: 14,color: Colors.white,),),),),],),);}
}

效果图如下

在这里插入图片描述

在这里插入图片描述

三、小结

flutter开发实战-ValueListenableBuilder实现局部刷新功能

学习记录,每天不停进步。

http://www.lryc.cn/news/253365.html

相关文章:

  • 通过时间交织技术扩展ADC采样速率的简要原理
  • FluxMQ—2.0.8版本更新内容
  • 计算机寄存器是如何实现的
  • 两数之和 三数之和 哈希方法
  • Object Detection in 20 Years: A Survey(2019.5)
  • Springboot 设置时区与日期格式
  • 从零开始学Go web——第一天
  • 6.Eclipse里下载Subclipse插件
  • 家用洗地机哪个品牌最好最实用?热门洗地机测评
  • 【C语言:自定义类型(结构体、位段、共用体、枚举)】
  • 【1day】华天软件 OAworkFlowService接口SQL注入漏洞学习
  • Oracle(2-11)RMAN Backups
  • 使用docker搭建『Gitea』私有仓库
  • CopyOnWriteArrayList怎么用
  • 旋转设备状态监测与预测性维护:提高设备可靠性的关键
  • 类和对象——(7)this指针
  • 回溯算法题型分类
  • ApplicationRunner 类
  • QT中的 容器(container)-大全
  • Docker配置镜像加速器
  • 飞致云1panel + 雷池WAF
  • 策略梯度简明教程
  • 鸿蒙原生应用/元服务开发-利用picker选择器来多选相册图片
  • java:封装统一的响应体code、data、msg、paging
  • leetcode算法之栈
  • 电脑上mp4视频文件无缩略图怎么办
  • 【Centos8】配置网络镜像源
  • 深入学习Synchronized各种使用方法
  • 【idea】设置鼠标滚轮控制缩放大小
  • 合并两个有序数组(leetcode_刷题1)