【Flutter·学习实践·UI篇】基础且重要的UI知识
前言
参考学习官网:《Flutter实战·第二版》
学习前先记住:Flutter 中万物皆为Widget,心中默念3次以上铭记于心。
这一点和开发语言Dart的变量一切皆是对象的概念,相互对应。
Widget
在前面的介绍中,我们知道在Flutter中几乎所有的对象都是一个 widget 。与原生开发中“控件”不同的是,Flutter 中的 widget 的概念更广泛,它不仅可以表示UI元素,也可以表示一些功能性的组件如:用于手势检测的 GestureDetector 、用于APP主题数据传递的 Theme 等等,而原生开发中的控件通常只是指UI元素。在后面的内容中,我们在描述UI元素时可能会用到“控件”、“组件”这样的概念,读者心里需要知道他们就是 widget ,只是在不同场景的不同表述而已。
Flutter 主要核心就是用于构建用户界面,说白了它做的界面可以跨平台,就只做界面,大部分开发认为 widget 就是一个控件,不必纠结于概念。
Widget 接口了解
- @immutable 代表 Widget 是不可变的,Flutter 中如果属性发生变化则会重新构建Widget树
- Widget 中定义的属性必须是 final
- Widget类继承自DiagnosticableTree,DiagnosticableTree即“诊断树”,提供调试信息。
- Key:主要的作用是决定是否在下一次
build时复用旧的 widget (决定的条件在canUpdate()方法中) - createElement():一个 widget 可以对应多个
Element(在我们开发过程中基本不会调用到) - debugFillProperties(...) 复写父类的方法,主要是设置诊断树的一些特性。
- canUpdate(...)是一个静态方法,是否用新的 widget 对象去更新旧UI树上所对应的Element对象的配置。(条件是:newWidget与oldWidget的runtimeType和key同时相等时就会用new widget去更新Element对象的配置,否则就会创建新的Element。)
Flutter中的四棵树
先看示意图:

最后一棵树是渲染树在上屏前会生成的 Layer 树,暂时不做讨论
- WidgetTree:存放渲染内容、它只是一个配置数据结构,创建是非常轻量的,在页面刷新的过程中随时会重建
- Element 是分离 WidgetTree 和真正的渲染对象的中间层, WidgetTree 用来描述对应的Element 属性,同时持有Widget和RenderObject,存放上下文信息,通过它来遍历视图树,支撑UI结构。
- RenderObject (渲染树)用于应用界面的布局和绘制,负责真正的渲染,保存了元素的大小,布局等信息,实例化一个 RenderObject 是非常耗能的
StatelessWidget
它继承自widget类,重写了createElement()方法
@override
StatelessElement createElement() => StatelessElement(this);
StatelessElement 间接继承自Element类,与StatelessWidget相对应(作为其配置数据)。
StatelessElement用于不需要维护状态的场景,它通常在build方法中通过嵌套其他 widget 来构建UI,在构建过程中会递归的构建其嵌套的 widget 。
StatefulWidget
和StatelessWidget一样,StatefulWidget也是继承自widget类,并重写了createElement()方法,不同的是返回的Element 对象并不相同;另外StatefulWidget类中添加了一个新的接口createState()。
StatefulWidget的类定义:
abstract class StatefulWidget extends Widget {const StatefulWidget({ Key key }) : super(key: key);@overrideStatefulElement createElement() => StatefulElement(this);@protectedState createState();
}
StatefulElement 间接继承自Element类,与StatefulWidget相对应(作为其配置数据)。StatefulElement中可能会多次调用createState()来创建状态(State)对象。
createState() 用于创建和 StatefulWidget 相关的状态,它在StatefulWidget 的生命周期中可能会被多次调用。
StatelessWidget 和 StatefulWidget 都是用于组合其他组件的,它们本身没有对应的 RenderObject。
StatelessWidget:无状态使用;
StatefulWidget:有状态,且可变时使用;
StatelessWidget和StatefulWidget一定要记住写UI经常用到。
State
一个 StatefulWidget 类会对应一个 State 类,State表示与其对应的 StatefulWidget 要维护的状态,State 中的保存的状态信息允许:
- 在 widget 构建时可以被同步读取。
- 在 widget 生命周期中可以被改变,当State被改变时,可以手动调用其setState()方法通知Flutter 框架状态发生改变,Flutter 框架在收到消息后,会重新调用其build方法重新构建 widget 树,从而达到更新UI的目的。
State 中有两个常用属性:
- widget,它表示与该 State 实例关联的 widget 实例,由Flutter 框架动态设置。
- context,StatefulWidget对应的 BuildContext,作用同StatelessWidget 的BuildContext。
State生命周期 :看官方实例
initState:当 widget 第一次插入到 widget 树时会被调用,对于每一个State对象,Flutter 框架只会调用一次该回调。
didChangeDependencies :当State对象的依赖发生变化时会被调用。
build:主要是用于构建 widget 子树。
didUpdateWidget:在 widget 重新构建时,Flutter 框架会调用widget.canUpdate来检测 widget 树中同一位置的新旧节点,然后决定是否需要更新,如果widget.canUpdate返回true则会调用此回调。
reassemble:热重载(hot reload)时会被调用,此回调在Release模式下永远不会被调用。
deactivate:State 对象从树中被移除时,会调用此回调。
dispose:当 State 对象从树中被永久移除时调用;通常在此回调中释放资源

在 widget 树中获取State对象
由于 StatefulWidget 的的具体逻辑都在其 State 中,所以很多时候,我们需要获取 StatefulWidget 对应的State 对象来调用一些方法。
获取state对象的几种方法
- context对象的findAncestorStateOfType()方法;
- ScaffoldState _state = context.findAncestorStateOfType<ScaffoldState>()!;
- 直接通过of静态方法来获取State对象:(ScaffoldState _state=Scaffold.of(context);)
- 通过GlobalKey
2. 通过GlobalKey来获取State对象//定义一个globalKey, 由于GlobalKey要保持全局唯一性,我们使用静态变量存储 static GlobalKey<ScaffoldState> _globalKey= GlobalKey(); ... Scaffold(key: _globalKey , //设置key... )_globalKey.currentState.openDrawer()
注意:使用 GlobalKey 开销较大,如果有其他可选方案,应尽量避免使用它。另外,同一个 GlobalKey 在整个 widget 树中必须是唯一的,不能重复。
相关文章:
【Flutter·学习实践·UI篇】基础且重要的UI知识
前言 参考学习官网:《Flutter实战第二版》 学习前先记住:Flutter 中万物皆为Widget,心中默念3次以上铭记于心。 这一点和开发语言Dart的变量一切皆是对象的概念,相互对应。 Widget 在前面的介绍中,我们知道在Flutt…...
【OpenCV】车牌自动识别算法的设计与实现
写目录一. 🦁 设计任务说明1.1 主要设计内容1.1.1 设计并实现车牌自动识别算法,基本功能要求1.1.2 参考资料1.1.3 参考界面布局1.2 开发该系统软件环境及使用的技术说明1.3 开发计划二. 🦁 系统设计2.1 功能分析2.1.1 车辆图像获取2.1.2 车牌…...
SpringBoot发送邮件
目录1. 获取授权码2. jar包引入3. 配置application4. 代码实现1. 获取授权码 以126邮箱为例,点开设置,选择POP3/SMTP/IMAP 开启POP3/SMTP服务,新增授权密码 扫码二维码,发送要求的短信内容到指定的号码即可,然后会返回…...
BigInteger类和BigDecimal类的简单介绍
文章目录📖前言:🎀BigInteger类和BigDecimal类的由来🎀BigDecimal类的优点🎀BigDecimal类容易引发的错误🏅处理方法📖前言: 本篇博客主要介绍BigInteger类和BigDecimal类的用途及常…...
mysql五种索引类型---实操版本
背景 最近学习了Mysql的索引,索引对于Mysql的高效运行是非常重要的,正确的使用索引可以大大的提高MySql的检索速度。通过索引可以大大的提升查询的速度。不过也会带来一些问题。比如会降低更新表的速度(因为不但要把保存数据还要保存一下索引…...
【微信小程序】-- 页面导航 -- 编程式导航(二十三)
💌 所属专栏:【微信小程序开发教程】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &…...
路由追踪工具 traceroute 使用技巧
路由追踪工具 traceroute 使用技巧路由追踪工作原理路由追踪实例1. 如何运行 traceroute2. 禁用 IP 地址和主机名映射3. 配置回复等待时间4. 配置每一跳的查询次数5. 配置 TTL 值我想知道一个数据包从出发地到目的地所遵循的路由,即所有转发实体(中间的路…...
NGINX学习笔记 - 一篇了解NGINX的基本概念(一)
NGINX是什么? NGINX是一款由俄罗斯人伊戈尔赛索耶夫使用C语言开发的、支持热部署的、轻量级的WEB服务器/反向代理服务器/电子邮件代理服务器,因为占用内存较少,启动极快,高并发能力强,所以在互联网项目中广泛应用。可…...
Spring-Cloud-Gateway的过滤器的执行顺序问题
过滤器的种类 Spring-Cloud-Gateway中提供了3种类型的过滤器,分别是:路由过滤器、Default过滤器和Global过滤器。 路由过滤器和Default过滤器 路由过滤器和Default过滤器本质上是同一种过滤器,只不过作用范围不一样,路由过滤器…...
Android性能优化的底层逻辑
前言性能优化仿佛成了每个程序员开发的必经之路,要想出人头地,与众不同,你还真需要下点功夫去研究Android的性能优化,比如说,从优化应用启动、UI加载、再到内存、CPU、GPU、IO、还有耗电等等,当你展开一个方…...
Gradle+SpringBoot多模块开发
关于使用Gradle结合SpringBoot进行多模块开发。 本来是打算使用buildSrc之类的,但是感觉好像好麻烦,使用这种方法就可以实现,没必要采用其他的。 我不怎么会表述,可能写的跟粑粑一样,哈哈哈哈 这是我的项目地址。 存在…...
Qt 之 emit、signals、slot的使用
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS&am…...
每日学术速递3.6
Subjects: cs.CV 1.Multi-Source Soft Pseudo-Label Learning with Domain Similarity-based Weighting for Semantic Segmentation 标题:用于语义分割的基于域相似性加权的多源软伪标签学习 作者:Shigemichi Matsuzaki, Hiroaki Masuzawa, Jun Miura …...
C# 将对象转换成字节数组(二进制数据)
在将自定义对象或者数组等这样的数据存储到数据库时往往需要转换成二进制字节,尤其是在一些O/RM数据库框架中,下面是转换的函数,一个是将对象转换成二进制字节数组,另一个是将从数据库中读取的二进制流转换成程序中的对象。 这里…...
巾帼绽芬芳 一起向未来(下篇)
编者按:为了隆重纪念纪念“三八”国际妇女节113周年,快来与你全方位、多层次分享交流“三八”国际妇女节的前世今生。分上篇(节日简介、节日发展和节日意义)、中篇(节日活动宗旨和世界各国庆祝方式)和下篇&…...
代码还原小试牛刀(一):魔改的MD5
一、目标 2023年了,MD5已经是最基础的签名算法了,但如果你还只是对输入做了简单的MD5,肯定会被同行们嘲笑。加点盐(salt)是一种基本的提升,但在这个就业形势严峻的时代,仅仅加盐肯定不够了。 …...
6. 找大佬
1 题目描述 找大佬成绩20开启时间2021年09月24日 星期五 18:00折扣0.8折扣时间2021年11月15日 星期一 00:00允许迟交否关闭时间2021年11月23日 星期二 10:00 众所周知,每个专业里都会有一些大佬隐藏在人群里。软件工程专业也是如此。今天的你就像从人群中找到真正的…...
【CSS】标签显示模式 ① ( 标签显示模式 | 块级元素 )
文章目录一、标签显示模式 ( 块级元素 | 行内元素 )二、块级元素1、块级元素简介2、块级元素特点3、文字块级元素4、代码示例一、标签显示模式 ( 块级元素 | 行内元素 ) 标签显示模式 : 指的是 标签显示的方式 , 标签类型有很多 , 不同的情景使用不同类型的标签 ; 块级元素 : …...
hive真实表空间大小统计
1. 问题 如果是采用hdfs上传加载的表、或者是flume直接写hdfs的表空间通常看hive的属性是不准确的。 2. 思路 为了使结果更精确,我们直接使用linux下命令统计hive仓库目录下的每个表对应的文件夹目录占用空间的大小。 3. 解决方法 这里建立三层表结构 ods: 原始…...
微信小程序引入Vant UI步骤
官方文档教程 1、通过 npm 安装 # 通过 npm 安装 npm i vant/weapp -S --production# 通过 yarn 安装 yarn add vant/weapp --production# 安装 0.x 版本 npm i vant-weapp -S --production2、修改 app.json 将 app.json 中的 “style”: “v2” 去除,小程序的新…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
倒装芯片凸点成型工艺
UBM(Under Bump Metallization)与Bump(焊球)形成工艺流程。我们可以将整张流程图分为三大阶段来理解: 🔧 一、UBM(Under Bump Metallization)工艺流程(黄色区域ÿ…...
WEB3全栈开发——面试专业技能点P4数据库
一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库,基于 mysql 库改进而来,具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点: 支持 Promise / async-await…...
GeoServer发布PostgreSQL图层后WFS查询无主键字段
在使用 GeoServer(版本 2.22.2) 发布 PostgreSQL(PostGIS)中的表为地图服务时,常常会遇到一个小问题: WFS 查询中,主键字段(如 id)莫名其妙地消失了! 即使你在…...
