Flutter中的Tree

一、Widget

组合类(Composite Widgets)

如Container、Scaffold、MaterialApp等,以及通过继承StatelessWidget和StatefulWidget的类。

代理类(Proxy Widgets)

如InheritedWidget,这是一种功能型组件,可以高效快捷地实现共享数据的跨组件传递;
InheritedWidget是一个代理类Widget,主要用于在Descendant Widgets之间传递共享信息;
通过使用InheritedWidget,可以在树结构中传递信息,当子类状态变更时,可以通知父类进行对应的变更;
ParentDataWidget主要用于配置Descendant Renderer Widget的布局信息;
与InheritedWidget的作用方向相反,ParentDataWidget为具有多个子类的RenderObjectWidget提供对应的配置等,例如Stack使用已定位好的父类Widget来定位每个子Widget。

绘制类(Render Object Widgets)

这类Widget几乎涵盖了屏幕上看到的所有UI,都是通过继承RenderObjectWidget实现的;
根据对应的Element,可以分为MultiChildRenderObjectWidget、SingleChildRenderObjectWidget和LeafRenderObjectWidget,其中LeafRenderObjectWidget是那些没有子节点的Widget。

StatefulWidget生命周期

可以分为三个阶段:创建、更新和销毁;
在创建阶段中,Widget会触发一系列生命周期方法来响应不同的事件;
这些方法包括createState、initState、didChangeDependencies和build;
createState方法会在Widget被创建时调用,用于创建一个新的State对象;
initState方法会在State对象被创建后调用,用于初始化State对象。didChangeDependencies方法会在State对象依赖的对象发生变化时调用,例如父Widget发生变化时;
build方法会在创建阶段和更新阶段都会被调用,用于构建UI界面;

在更新阶段中,Widget会触发一系列生命周期方法来响应不同的事件;
这些方法包括didUpdateWidget和setState;
didUpdateWidget方法会在Widget属性发生变化时调用,例如父Widget的属性发生变化时;
setState方法会在State对象的状态发生变化时调用,用于更新状态;

在销毁阶段中,Widget会触发一系列生命周期方法来响应不同的事件;
这些方法包括deactivate和dispose;
deactivate方法会在State对象暂时从视图树中移除时调用,例如当页面被覆盖时;
dispose方法会在永久从视图树中移除时调用,通常用于释放所有资源。

Widget的更新条件

setState()方法被调用、依赖的变量或数据发生变化、parent widget发生变化、Widget Tree重建等;
总的来说就是Flutter会递归遍历新旧Widget Tree的节点,对比它们的runtimeType和key属性是否相同,如果相同就会认为不需要更新。

Key

Key共分为LocalKey和GlobalKey,通过比较hashCode来判断两个Key是否相等,在使用中需要注意Key的唯一性;
GlobalKey是一个全局唯一的Key,可以在整个应用中引用;
LocalKey直接继承至Key,它应用于拥有相同父Element的Widget进行比较的情况;
LocalKey包括ValueKey(最常用的Key类型,它将一个值赋予给Key)、ObjectKey(与ValueKey类似,但是ObjectKey使用的是对象的引用)、UniqueKey(每次创建都会生成一个唯一的Key);
PageStorageKey继承自ValueKey,是用于存储用户滚动位置的专用key,以便应用可以保留当前的滚动位置,供后续使用。

二、Element、RenderObject、Paint

从Tree到渲染

对于一个StatefulWidget,当StatefulWidget被插入到Widget Tree中时,Flutter框架会调用其createElement()方法;
createElement()方法返回一个StatefulElement实例,StatefulElement随后被挂载到Element Tree上;

StatefulElement通过调用StatefulWidget的createState()方法来创建一个状态对象(State);
这个状态对象负责管理StatefulWidget的状态,并可以在状态变化时触发重建;

在适当的时机(如widget首次构建或状态变化时),Flutter框架会调用状态对象的build()方法;
build()方法返回一个Widget Tree,这个树描述了应该如何在屏幕上呈现该widget;
StatefulElement会将自身作为BuildContext传入到build()方法中,以便在Widget Tree中可以使用context相关的功能;

build()方法返回的Widget Tree最终会被转换为一系列的RenderObject;
每个widget都有一个对应的RenderObject类型,用于实际的布局和绘制工作;
这个转换过程是通过Widget Tree的深度优先遍历来完成的,每个widget都会调用其自己的createElement()和build()方法来参与这个过程;
最终,每个widget都会与一个或多个RenderObject关联起来,形成一个Render object Tree;

一旦Render object Tree被构建完成,Flutter就会开始布局和绘制过程;
布局过程确定每个render object的大小和位置;
绘制过程则使用Skia图形库(或其他平台特定的图形API)来将render object渲染到屏幕上。

总结

Widget定义了用户界面的结构和样式,是声明性的;
Element是Widget的实例化对象,负责维护UI的状态并与RenderObject进行协调;
RenderObject负责实际的布局和绘制工作,使用Paint对象来执行绘图操作;
Paint定义了绘图操作的样式和效果。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql聚簇索引和非聚簇索引

目录 InnoDB引擎MylSAM引擎聚簇索引的优点和缺点参考 聚簇索引和非聚簇索引的区别:叶节点是否存放一整行记录。 聚簇索引:将数据存储与索引放到了一块,索引结构的叶子节点保存了行数据。 非聚簇索引:将数据与索引分开存储,索引结构的叶子节点指向了数据对…

SpringBoot+ShardingSphereJDBC实战(读写分离,分库分表,垂直拆分、水平拆分)附源码

参考:https://www.51cto.com/article/747736.html https://blog.csdn.net/qq_41581588/article/details/126966665 源码地址:gitgitee.com:jackXUYY/springboot-example.git 读写分离测试 我们启用后缀名为dev的配置文件,如下,…

深入理解SqlSugar ORM框架的使用与实战

一、引言 SqlSugar 是一个轻量级的 ORM(对象关系映射)库,用于在 C# 中与 SQL 数据库进行交互。它提供了一个简单易用的 API,使得开发人员可以以对象的形式而不是原始 SQL 语句进行工作。在本文中,我们将通过实例代码的…

C++入门【18-C++ 指针】

C 指针 学习 C 的指针既简单又有趣。通过指针,可以简化一些 C 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。所以,想要成为一名优秀的 C 程序员,学习指针是很有必要的。 正如您所知…

nginx 一、安装与conf浅析

文章目录 一、安装nginxdocker方式安装linux方式安装Ubuntu 或 Debian 系统:CentOS 或 RHEL 系统: macOS 系统(使用 Homebrew):Windows 系统: 二、nginx.conf浅析 Nginx(发音为“engine-x”&…

椭圆中点算法

原理 椭圆的扫描转换与圆的扫描转换有相似之处,但也有不同,主要区别是椭圆弧上存在改变主位移方向的临界点。瞬时针绘制四分椭圆弧的中点算法,根据对称性可以绘制完整的椭圆。 四分椭圆弧 中心在原点,长半轴为 a a a、短半轴为…

01-03

利用模板类完成顺序表

简易电子琴

#include<reg51.h> //包含51单片机寄存器定义的头文件 sbit P14P1^4; //将P14位定义为P1.4引脚 sbit P15P1^5; //将P15位定义为P1.5引脚 sbit P16P1^6; //将P16位定义为P1.6引脚 sbit P17P1^7; //将P17位定义为P1.7引脚 unsigned char keyval; …

Redis 的常用命令

一、Redis 通用命令 TYPE key&#xff1a;返回 key 所储存的值的类型。 OBJECT ENCODING key&#xff1a;返回key所储存的值的底层编码方式。 DEL key&#xff1a;该命令用于在 key 存在时删除 key。 EXPIRE key seconds&#xff1a;设置指定key的过期时间。 RENAME key newke…

高端大气的在线文档

背景 产品介绍&#xff0c;帮助手册&#xff0c;操作手册&#xff0c;开发说明&#xff0c;个人的简单网站等等&#xff0c;都需要一个在线的文档&#xff0c;特别是开源社区的在线文档也非常需要&#xff0c;开源社区也为此提供了大量的工具。如何找到一款高端大气的&#xf…

使用MyBatis实现动态SQL查询的最佳实践

在数据库操作中&#xff0c;动态SQL查询是一种非常常见的需求。MyBatis作为一款优秀的持久层框架&#xff0c;提供了强大的动态SQL功能&#xff0c;允许开发者根据不同条件动态构建SQL查询语句&#xff0c;从而灵活地执行数据库操作。本文将深入探讨MyBatis中动态SQL查询的实现…

解决Golang WriteHeader设置后,Content-Type失效的问题

场景 最近笔者在研究web框架过程中&#xff0c;发现了一个响应类型的问题&#xff0c;困扰许久&#xff0c;原因就是设置了响应状态码后&#xff0c;然后设置响应类型为application/json。在实际请求后&#xff0c;响应类型变成了text/plain; charsetutf-8格式。 问题解决&…

SQL备忘--子查询与ALL/ANY运算符

概念 在SQL查询语句中包含了其他的查询语句&#xff0c;出现了SQL语句的嵌套&#xff0c;即为使用了嵌套子查询 子查询用法 子查询可以用在&#xff1a; SELECT查询字段中FROM表名语句中WHERE条件中 由此可见子查询用法广泛&#xff0c;可用在SQL基本语句的每个位置。但具…

学习Go语言Web框架Gee总结--前缀树路由Router(三)

学习Go语言Web框架Gee总结--前缀树路由Router router/gee/trie.gorouter/gee/router.gorouter/gee/context.gorouter/main.go 学习网站来源&#xff1a;Gee 项目目录结构&#xff1a; router/gee/trie.go 实现动态路由最常用的数据结构&#xff0c;被称为前缀树(Trie树) 关…

python代码大全(持续更新)

读写文件 # 读取文件 with open(file.txt, r) as file:content file.read()# 写入文件 with open(file.txt, w) as file:file.write(Hello, World!)HTTP请求 import requestsresponse requests.get(https://api.example.com/data) data response.json()JSON处理 import j…

机器学习中聚类算法-简单介绍

聚类算法 聚类算法&#xff1a; 将数据分成不同的组&#xff0c;如K均值&#xff08;K-Means&#xff09;和层次聚类&#xff08;Hierarchical Clustering&#xff09;。 聚类是机器学习中一类重要的无监督学习问题&#xff0c;其目标是将数据集中的样本划分为不同的组&#x…

【AI】目标检测算法DETR源码解析及推理测试

说到目标检测&#xff0c;自然而然我们会想到YOLO这个框架&#xff0c;YOLO框架已经发展到V8版本了&#xff0c;各种应用也比较成熟&#xff0c;不过我最近在研究Transformer&#xff0c;今天的主角是Transformer在目标检测的开山之作&#xff1a;DETR&#xff1a;End-to-End O…

FairGuard游戏加固产品常见问题解答

针对日常对接中&#xff0c;各位用户对FairGuard游戏加固方案在安全性、稳定性、易用性、接入流程等方面的关注&#xff0c;我们梳理了相关问题与解答&#xff0c;希望可以让您对产品有一个初步的认知与认可。 Q1:FairGuard游戏加固产品都有哪些功能? A&#xff1a;FairGuar…

结构体详解

结构体&#xff1a; 一系列具有相同类型或不同类型的数据构成的数据集合&#xff0c;也叫结构 结构体可以用来封装一些属性来组成新的类型。 结构体的大小&#xff1a; 结构体的大小不是结构体元素单纯相加。内存对齐&#xff08;若计算机使用32位字长的cpu&#xff0c;对32位的…

【算法】dp题单

题单链接&#xff1a; https://vjudge.net/contest/574209#overview 目录 1. 洛谷 P1020 导弹拦截 &#xff08;dp二分Dilworth 定理&#xff09; 2. P1439 最长公共子序列&#xff08;二分求最长公共子序列&#xff09; 3. 洛谷 P1854 花店橱窗布置 &#xff08;线性dp 用…