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

Flutter:key的作用原理(LocalKey ,GlobalKey)

第一段代码实现的内容:创建了3个块,随机3个颜色,每次点击按钮时,把第一个块删除

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_one/demo.dart';void main() {runApp(const App());
}class App extends StatelessWidget {const App({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return const MaterialApp(home: KeyDemo(),);}
}class KeyDemo extends StatefulWidget {const KeyDemo({Key? key}) : super(key: key);@overrideState<KeyDemo> createState() => _KeyDemoState();
}class _KeyDemoState extends State<KeyDemo> {// 生成三个无状态的块List<Widget> items = [StlItem('1'),StlItem('2'),StlItem('3')];@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('KeyDemo'),centerTitle: true,),body: Row(mainAxisAlignment: MainAxisAlignment.center,children: items,),floatingActionButton: FloatingActionButton(child: Icon(Icons.add),onPressed: (){setState(() {items.removeAt(0); // 点击按钮把第一个删除});}),);}
}

先调用无状态的StatelessWidget ,当删除发生时看看效果

class StlItem extends StatelessWidget {final String title;StlItem(this.title,{Key? key}) : super(key: key);// 随机的颜色final color = Color.fromRGBO(Random().nextInt(256), Random().nextInt(256), Random().nextInt(256), 1.0);@overrideWidget build(BuildContext context) {return Container(width: 100,height: 100,child: Text(title),color: color,);}
}

发生删除时:
在这里插入图片描述
删除后
在这里插入图片描述
总结发现,如果是无状态的StatelessWidget 即使不传key:StlItem(this.title,{Key? key}) : super(key: key);
也能正常删除。

下面看下有状态的StatelessWidget,不传key会出现什么BUG

// 第一段代码中:生成三个有状态的块
List<Widget> items = [StfulItem('1'),StfulItem('2'),StfulItem('3')
];// 有状态
class StfulItem extends StatefulWidget {final String title;StfulItem(this.title,{Key? key}) : super(key: key);@overrideState<StfulItem> createState() => _StfulItemState();
}class _StfulItemState extends State<StfulItem> {// 随机的颜色final color = Color.fromRGBO(Random().nextInt(256), Random().nextInt(256), Random().nextInt(256), 1.0);@overrideWidget build(BuildContext context) {return Container(width: 100,height: 100,child: Text(widget.title),color: color,);}
}

删除前
在这里插入图片描述
删除后
在这里插入图片描述
发现问题了:我删除的是第一条数据,发现文字1正常删除,但是颜色怎么是把颜色3给删除了呢??

源码中,StatelessWidgetStatefulWidget都继承Widget

abstract class StatefulWidget extends Widget{}

而在Widget中有这样一个方法,Flutter的增量渲染就是通过canUpdate来判断哪里需要更新数据。

static bool canUpdate(Widget oldWidget, Widget newWidget) {return oldWidget.runtimeType == newWidget.runtimeType&& oldWidget.key == newWidget.key;
}

Flutter中的3棵树中,Widget树和Element树

每创建一个Widget,都会有对应的Element
在这里插入图片描述
当删除第一个WidgetElement就会调用canUpdate更新数据,Element是按顺序判断,它会拿Element111和删除后的Widget222进行对比

oldWidget.runtimeType == newWidget.runtimeType 旧的部件类型和新的部件类型是一样的,oldWidget.key == newWidget.key;旧的没有传key和新的也没传key,结果那就是true,增量渲染发现可以复用,Element111就指向了Widget222
最后对比到Element333,发现Widget树中已经没有了,Element333就被删除了。

那么颜色为什么会错了,因为颜色是保存在State中,State是保存在Element中,所以最后一个颜色canUpdate时被删除了。

在这里插入图片描述

加上key之后解决这个BUG

List<Widget> items = [StfulItem('1',key: const ValueKey('1'),),StfulItem('2',key: const ValueKey('2'),),StfulItem('3',key: const ValueKey('3'),)
];

key的原理

Key本身是一个抽象类,有一个工厂构造方法,创建ValueKey
直接子类主要有:LocalKey 和 GlobalKeyGlobalKey:帮助我们访问某个Widget的信息LocalKey :它用来区别哪个Element保留,哪个Element要删除ValueKey 以值作为参数(数字、字符串)ObjectKey:以对象作为参数UniqueKey:创建唯一标识

GlobalKey使用

import 'package:flutter/material.dart';
class GlobalKeyDemo extends StatelessWidget {// 定义:GlobalKey<拿谁的数据> 变量 = GlobalKey();final GlobalKey<_childPageState> _globalKey = GlobalKey();GlobalKeyDemo({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('GlobalKeyDemo'),),body: childPage(key: _globalKey,),floatingActionButton: FloatingActionButton(onPressed: (){// _globalKey  就能访问到 _childPageState 中的属性,进行修改_globalKey.currentState!.setState((){_globalKey.currentState!.data = 'hello word';_globalKey.currentState!.count++;});},child: const Icon(Icons.add),),);}
}class childPage extends StatefulWidget {const childPage({Key? key}):super(key: key);@overrideState<childPage> createState() => _childPageState();
}class _childPageState extends State<childPage> {int count = 0;String data = 'heelo';@overrideWidget build(BuildContext context) {return Column(children: [Text(count.toString()),Text(data),],);}
}

除了定义GlobalKey外,还可以使用InheritedWidget数据共享。

相关文章:

Flutter:key的作用原理(LocalKey ,GlobalKey)

第一段代码实现的内容&#xff1a;创建了3个块&#xff0c;随机3个颜色&#xff0c;每次点击按钮时&#xff0c;把第一个块删除 import dart:math; import package:flutter/material.dart; import package:flutter_one/demo.dart;void main() {runApp(const App()); }class App…...

R语言基础入门详解

文章目录 R语言基础入门详解一、引言二、R语言环境搭建1、安装R和RStudio1.1、步骤1.2、获取工作目录 三、R语言基础2、语法基础2.1、赋值操作2.2、注释 3、数据类型与结构3.1、向量3.2、矩阵 4、基本操作4.1、数据读取4.2、数据可视化 四、R语言使用示例4.1、统计分析示例4.2、…...

django启动项目报错解决办法

在启动此项目报错&#xff1a; 类似于&#xff1a; django.core.exceptions.ImproperlyConfigured: Requested setting EMOJI_IMG_TAG, but settings are not c启动方式选择django方式启动&#xff0c;以普通python方式启动会报错 2. 这句话提供了对遇到的错误的一个重要线索…...

详细描述一下Elasticsearch搜索的过程?

大家好&#xff0c;我是锋哥。今天分享关于【详细描述一下Elasticsearch搜索的过程&#xff1f;】面试题。希望对大家有帮助&#xff1b; 详细描述一下Elasticsearch搜索的过程&#xff1f; Elasticsearch 的搜索过程是其核心功能之一&#xff0c;允许用户对存储在 Elasticsea…...

Spring、SpringMVC、SpringBoot、Mybatis小结

Spring Spring是一个轻量级的控制反转&#xff08;IoC&#xff09;和面向切面&#xff08;AOP&#xff09;的容器&#xff08;框架&#xff09; Spring框架的核心特性包括依赖注入&#xff08;Dependency Injection &#xff0c;DI&#xff09;、面向切面编程&#xff08;Aspe…...

.NET 9 运行时中的新增功能

本文介绍了适用于 .NET 9 的 .NET 运行时中的新功能和性能改进。 文章目录 一、支持修剪的功能开关的属性模型二、UnsafeAccessorAttribute 支持泛型参数三、垃圾回收四、控制流实施技术.NET 安装搜索行为性能改进循环优化感应变量加宽Arm64 上的索引后寻址强度降低循环计数器可…...

Linux下安装mysql8.0版本

先确定我的下载安装的目录,安装文件是下载在 /opt/install 目录下面 (安装地址不同的话注意修改地址) 1.在线下载 wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz2.解压 tar -xvf mysql-8.0.20-linux-glibc2.12-x86_64.t…...

kvm-dmesg:从宿主机窥探虚拟机内核dmesg日志

在虚拟化环境中&#xff0c;实时获取虚拟机内核日志对于系统管理员和开发者来说至关重要。传统的 dmesg 工具可以方便地查看本地系统的内核日志&#xff0c;但在KVM&#xff08;基于内核的虚拟机&#xff09;环境下&#xff0c;获取虚拟机内部的内核日志则复杂得多。为了简化这…...

植物明星大乱斗15

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 player.hplayer.cppparticle.hparticle.cpp player.h #pragma once #include <graphics.h> #include "vector2.h" #include "animation.h" #include "playerID.h" #include &…...

go-zero(三) 数据库操作

go-zero 数据库操作 在本篇文章中&#xff0c;我们将实现一个用户注册和登录的服务。我们将为此构建一个简单而高效的 API&#xff0c;包括请求参数和响应参数的定义。 一、Mysql连接 1. 创建数据库和表 在 MySQL 中创建名为 test_zero的数据库&#xff0c;并创建user 表 …...

SQL面试题——间隔连续问题

间隔连续问题 某游戏公司记录的用户每日登录数据如下 +----+----------+ | id| date| +----+----------+ |1001|2021-12-12| |1001|2021-12-13| |1001|2021-12-14| |1001|2021-12-16| |1001|2021-12-19| |1001|2021-12-20| |1002|2021-12-12| |1002|2021-12-16| |1002|…...

vim配置 --> 在创建的普通用户下

在目录/etc/ 下面&#xff0c;有个名为vimrc 的文件&#xff0c;这是系统中公共的vim配置文件对所有用户都有效 我们现在创建一个普通用户 dm 创建好以后&#xff0c;我们退出重新链接 再切换到普通用户下 再输入密码&#xff08;是不显示的&#xff0c;输入完后&#xff0c;…...

(计算机毕设)基于SpringBoot+Vue的房屋租赁系统的设计与实现

博主可接毕设设计&#xff01;&#xff01;&#xff01; 各种毕业设计源码只要是你有的题目我这里都有源码 摘 要 社会的发展和科学技术的进步&#xff0c;互联网技术越来越受欢迎。网络计算机的生活方式逐渐受到广大人民群众的喜爱&#xff0c;也逐渐进入了每个用户的使用。互…...

【含开题报告+文档+PPT+源码】基于SpringBoot的医院药房管理系统

开题报告 在科技迅速发展的今天&#xff0c;各行各业都在积极寻求与现代技术的融合&#xff0c;以提升自身的运营效率和竞争力。医疗行业作为关乎国计民生的关键领域&#xff0c;其信息化建设的步伐尤为迅速。医院药房作为医疗体系中的核心环节&#xff0c;其管理效率和服务质…...

基于SpringBoot的“数码论坛系统设计与实现”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“数码论坛系统设计与实现”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体结构图 系统首页界面图 数码板…...

Linux-第2集-打包压缩 zip、tar WindowsLinux互传

欢迎来到Linux第2集&#xff0c;这一集我会非常详细的说明如何在Linux上进行打包压缩操作&#xff0c;以及解压解包 还有最最重要的压缩包的网络传输 毕竟打包压缩不是目的&#xff0c;把文件最终传到指定位置才是目的 由于打包压缩分开讲没有意义&#xff0c;并且它们俩本来…...

项目进度计划表:详细的甘特图的制作步骤

甘特图&#xff08;Gantt chart&#xff09;&#xff0c;又称为横道图、条状图&#xff08;Bar chart&#xff09;&#xff0c;是一种用于管理时间和任务活动的工具。 甘特图由亨利劳伦斯甘特&#xff08;Henry Laurence Gantt&#xff09;发明&#xff0c;是一种通过条状图来…...

Cargo Rust 的包管理器

Cargo->Rust 的包管理器 Cargi简介Cargo 的主要功能1. 创建项目2. 管理依赖3. 构建项目4. 运行项目5. 测试代码6. 检查代码7. 生成文档8. 发布和分享包 Cargo 的核心文件1. Cargo.toml2. Cargo.lock **Cargo 的生态系统** 常用命令总结Hello, Cargo! 示例 Cargi简介 Cargo …...

【Rust 编程语言工具】rustup-init.exe 安装与使用指南

rustup-init.exe 是用于安装和管理 Rust 编程语言工具链的 Windows 可执行文件。Rust 是一种系统级编程语言&#xff0c;旨在提供安全、并发和高性能的功能。rustup-init.exe 是官方提供的安装器&#xff0c;用于将 Rust 安装到 Windows 操作系统中&#xff0c;并配置相关环境。…...

集群聊天服务器(12)nginx负载均衡器

目录 负载均衡器nginx负载均衡器优势 如何解决集群聊天服务器跨服务器通信问题&#xff1f;nginx的TCP负载均衡配置nginx配置 负载均衡器 目前最多只能支持2w台客户机进行同时聊天 所以要引入集群&#xff0c;多服务器。 但是客户连哪一台服务器呢&#xff1f;客户并不知道哪一…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...