StatefulBuilder 和 Builder

前言

果然了解的越多,越发现自己狗屁都不是。StatefulBuilderBuilder 之前真的不知道。还是在 对话框状态管理
中了解到了这两个东西。

简介

以下内容来自通义灵码

在Flutter中,StatefulBuilderBuilder 都是用来动态构建 widget 树的组件,但它们在处理状态管理和构建上下文方面有所不同:

StatefulBuilder

  • StatefulBuilder 是一个特殊的 widget,主要用于那些本身不是 StatefulWidget 但却需要在构建过程中更改和反应状态变化的场景。它接收一个 builder 函数作为参数,这个函数会在状态更改时被调用并重新构建其内部 widget 树。
  • 使用 StatefulBuilder 时,你可以直接在其 builder 方法内调用提供的 _setState 参数来更新局部状态,并立即触发内部 widget 树的重建,而无需刷新整个页面或父级 StatefulWidget 的状态。
StatefulBuilder(
  builder: (BuildContext context, void Function(void Function()) setState) {
    bool isChecked = ...; // 可变状态
    return Checkbox(
      value: isChecked,
      onChanged: (bool newValue) {
        setState(() {
          isChecked = newValue;
        });
      },
    );
  },
);

Builder

  • Builder widget 不具备自身的状态管理能力,但它主要用于构建作用域内的BuildContext,特别是在涉及到InheritedWidget、Theme、Navigator等需要访问新构建环境的场景下。
  • Builder 主要用于将现有的 build 方法内部的上下文传递给其内部的 builder 函数,这样就可以在新的上下文中构建子 widget。这有助于隔离环境影响,尤其是在处理多个嵌套的 Consumer, StreamBuilder 或者 InheritedWidget 时。
Builder(
  builder: (BuildContext context) {
    // 这里可以使用新的BuildContext来构建子widget
    return Container(...);
  },
)

简而言之:

  • StatefulBuilder 允许你在没有独立 StatefulWidget 的情况下,在 widget 树的任何位置动态地更新状态。
  • Builder 则是为了获取或创建一个新的构建上下文,以便于在不同的环境中正确构建和访问 widget。它本身不涉及状态管理,更多关注的是构建环境的控制与传递。

案例

上面那篇文章里有对应的例子。这里也只是对其记录和学习。

    Future<bool?> showDeleteDialog() {
      // 记录是否选中
      bool isChecked = true;

      return showDialog<bool>(
          context: context,
          builder: (context) {
            return AlertDialog(
              title: const Text("提示"),
              content: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                // 高度设置为最小
                mainAxisSize: MainAxisSize.min,
                children: [
                  const Text("是否删除?"),
                  Row(
                    children: [
                      const Text("同时删除子目录?"),
                      Checkbox(
                          value: isChecked,
                          onChanged: (bool? value) {
                            isChecked = value!;
                          })
                    ],
                  )
                ],
              ),
              actions: [
                TextButton(
                    onPressed: () {
                      Navigator.pop(context, false);
                    },
                    child: const Text("取消")),
                TextButton(
                    onPressed: () {
                      // 返回选中状态
                      Navigator.pop(context, isChecked);
                    },
                    child: const Text("确定")),
              ],
            );
          });
    }

在这里插入图片描述

可以看出,UI没有被更新,文章中也给出了解释:

对话框也是通过路由的方式来实现的,那么上面的代码实际上就等同于企图在父路由中调用setState来让子路由更新,这显然是不行的!简尔言之,根本原因就是context不对。

解决方法那就是使用 StatefulBuilderBuilder 获取到独立的context

Row(
  children: [
    const Text("同时删除子目录?"),
    StatefulBuilder(builder: (context, setState) {
      return Checkbox(
          value: isChecked,
          onChanged: (bool? value) {
            setState(() {
              isChecked = value!;
            });
          });
    })
  ],
)
Row(
   children: [
     const Text("同时删除子目录?"),
     Builder(builder: (context) {
       return Checkbox(
           value: isChecked,
           onChanged: (bool? value) {
             (context as Element).markNeedsBuild();
             isChecked = value ?? false;
           });
     })
   ],
 )

在这里插入图片描述
StatefulBuilder中会提供一个setState用来更新局部状态,触发UI更新。
Builder 则是为了获取或创建一个新的构建上下文,调用ElementmarkNeedsBuild()方法来进行局部状态更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/496236.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年第十届国际虚拟现实大会(ICVR 2024)即将召开!

会议面向虚拟现实、增强现实、人工智能等互联网新技术领域的专家及学者&#xff0c; 致力于共同促进国内外虚拟现实的发展与应用。 2014年至今&#xff0c;ICVR在全球新加坡&#xff0c;美国洛杉矶&#xff0c;中国成都&#xff0c;香港等国家及地区召开&#xff0c;面向虚拟现…

Git_常用命令+代码冲突解决方案

文章目录 基本命令的使用查看git的当前版本初始化配置设置用户名及邮箱设置仓库的认证方式查看当前配置 创建仓库从远程服务器克隆仓库创建本地仓库 添加和提交文件工作区域和文件状态工作区域文件状态 查看文件状态及分支信息查看暂存区的内容添加文件提交文件查看提交日志回退…

ETLCloud结合Oracle实现CDC

CDC&#xff0c;即Change Data Capture&#xff08;变更数据捕获&#xff09;功能&#xff0c;主要针对实时数据同步和更新场景&#xff0c;能够实时监测数据库中的数据变化&#xff0c;并将发生变化的数据进行高效精准地捕获和传输&#xff0c;极大地提高了数据处理的效率以及…

ATFX汇市:美联储理事沃勒表示, 降低通胀的进展已经放缓,美指受提振

ATFX汇市&#xff1a;昨日&#xff0c;美联储理事在纽约经济俱乐部发表演讲&#xff0c;期间提到&#xff1a;第四季度国内生产总值&#xff08;GDP&#xff09;数据以及1月份就业增长和通胀数据比预期的要热&#xff0c;这意味着不急于开始降息以使货币政策立场正常化&#xf…

蓝桥杯-正则问题

#include<iostream> #include<string> #include<algorithm> using namespace std;int pos 0, l;//pos当前遍历到的位置&#xff0c;l是正则式的长度 string s;int dfs(){int temp 0, ans 0;//temp保存左半部分 while(pos < l){if(s[pos] (){pos;//跳…

JAVA_for - each循环

本章咱们聊聊简单的for-each循环&#xff1a;看完这章&#xff0c;写个test代码&#xff0c;以后写for-each循环应该就是探囊取物&#xff0c;胸有成竹。 for-each循环基本语法 for(元素类型 元素变量 : 数组名) {//操作语句 } 简单说几句&#xff1a; for-each循环是for循环…

Games104 听后笔记

1、为什么UE5要自己写一套STL库 因为传统的STL库中&#xff0c;例如&#xff1a;vector&#xff0c;它一般采用的是双倍扩容法&#xff0c;加入1000个数据装满了&#xff0c;现在需要又加一个&#xff0c;那么就开辟了2000个数据的空间&#xff0c;那么当前就又999的数据空间暂…

Java的字符串的基础知识(必看)

目录 Java的字符串的基础知识(必看) String API的使用 String概述 创建String对象的两种方式 号比的是什么? 难点 经典String案例 易错点 StringBuilder 疑难点: StringJoiner 字符串相关类的底层原理 中文的存储原理 String的常见的构造方法 Java的字符串的基础…

github加速神器!解决github巨慢的问题,并且能够加速下载!另外推荐GitKraken -- 超好用的 Git 可视化工具

FastGithub github加速神器&#xff0c;解决github打不开、用户头像无法加载、releases无法上传下载、git-clone、git-pull、git-push失败等问题。 下载地址&#xff1a; 清华云盘 2 部署方式 2.1 windows-x64桌面 双击运行FastGithub.UI.exe 2.2 windows-x64服务 fastgi…

WorkPlus最佳的内网通讯软件解决方案,助力企业构建高效沟通环境

高效的内部通讯对于团队协作和工作效率至关重要&#xff0c;而选择适合的内网通讯软件&#xff0c;能够提升企业的通讯效能。WorkPlus以其卓越的性能和全面的功能&#xff0c;成为企业内网通讯软件的最佳选择。 为何选择WorkPlus作为企业的内网通讯软件呢&#xff1f;首先&…

西藏实景三维技术研讨交流会成功举办

2024年3月21-22日&#xff0c;西藏自治区“实景三维技术研讨交流会”在拉萨成功举办。 本次会议由西藏自治区自然资源厅、自然资源部重庆测绘院指导&#xff0c;西藏自治区测绘学会、西藏自治区地理信息产业协会主办&#xff0c;武汉大势智慧科技有限公司&#xff08;后简称“…

Java多线程实战-从零手搓一个简易线程池(二)线程池与拒绝策略实现

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️本系列源码仓库&#xff1a;多线程并发编程学习的多个代码片段(github) &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正…

【每日一题 | 动态规划】访问完所有房间的第一天

文章目录 Tag题目来源解题思路方法一&#xff1a;动态规划 写在最后 Tag 【动态规划】【数组】【2024-03-28】 题目来源 1997. 访问完所有房间的第一天 解题思路 方法一&#xff1a;动态规划 定义状态 定义 f[i] 表示第一次到达房间 i 的日期编号。 根据题意&#xff0c;…

VMware vSAN OSA存储策略 - 基于虚拟机的分布式对象存储

简介 博客&#xff1a;https://songxwn.com/ 存储策略 (Storage Policy) 是管理员定义的一组规则&#xff0c;这组规则定义了数据对象在 vSAN 存储上是如何保存的&#xff0c;存储策略定义了数据存储的可靠性、访问性能等特性。vSAN 提供了基于存储策略的存储管理 SPBM (Stor…

upload-labs-master靶场训练笔记

2004.2.17 level-1 &#xff08;前端验证&#xff09; 新建一个写有下面一句话木马的php文件&#xff0c;然后把后缀改为png <?php eval($_POST["abc"]); ?> 用bp抓包后更改文件后缀为php 再用蚁剑等工具链接即可拿下shell level-2 &#xff08;后端…

js改变图片曝光度(高亮度)

方法一&#xff1a; 原理&#xff1a; 使用canvas进行滤镜操作&#xff0c;通过改变图片数据每个像素点的RGB值来提高图片亮度。 缺点 当前项目使用的是svg&#xff0c;而不是canvas 调整出来的效果不是很好&#xff0c;图片不是高亮&#xff0c;而是有些发白 效果 代码 …

量子通信达新高度!两大诺奖技术联手,铸就前所未有的高效纠缠光子源

滑铁卢大学量子计算研究所&#xff08;IQC&#xff09;的科学家们成功地融合了两项诺贝尔奖级别的研究成果&#xff0c;从而在量子通信领域取得了重大进展。他们现在能够通过量子点技术高效生成几乎完美的纠缠光子对&#xff0c;这一突破性成果已在《通信物理学》&#xff08;C…

实例:NX二次开发求取封闭曲线的面积(多个封闭曲线)

一、概述 最近在NX二次开发群里有人推了一篇关于写求取封闭曲线面积的文章。针对小白的我决定试着做一做&#xff0c;期间遇到了很多问题&#xff0c;全部用NXOpenC通过录制代码进行修改&#xff0c;最后发现老是有问题&#xff0c;后来通过ufun转化解决了问题&#xff0c;个人…

如何使用在项目中使用echarts

一、使用echarts的好处和作用 ECharts 是一个强大的数据可视化库&#xff0c;主要用于在网页上创建丰富多彩的交互式图表和地图。一些 ECharts 的好处和作用包括&#xff1a; 好处&#xff1a; 丰富的图表类型&#xff1a;ECharts 提供了各种常见的图表类型&#xff0c;如折线…

python的一些知识点

在C C Java中&#xff0c;基本数据类型变量&#xff08;将常量数据存储在变量空间当中&#xff09; int a 3; int b 4; 在C C中&#xff0c;指针变量&#xff08;存储的是变量的物理内存地址&#xff09; int a 3; int* b; b &a; int** c; c &b; printf("%d&…