【Flutter·学习实践·UI篇】基础且重要的UI知识

2023-05-16

前言

参考学习官网:《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);
    
  @override
  StatefulElement createElement() => StatefulElement(this);
    
  @protected
  State createState();
}

StatefulElement 间接继承自Element类,与StatefulWidget相对应(作为其配置数据)。StatefulElement中可能会多次调用createState()来创建状态(State)对象。

createState() 用于创建和 StatefulWidget 相关的状态,它在StatefulWidget 的生命周期中可能会被多次调用。

StatelessWidget 和 StatefulWidget 都是用于组合其他组件的,它们本身没有对应的 RenderObject。

StatelessWidget:无状态使用;

StatefulWidget:有状态,且可变时使用;

StatelessWidget和StatefulWidget一定要记住写UI经常用到。 

State

一个 StatefulWidget 类会对应一个 State 类,State表示与其对应的 StatefulWidget 要维护的状态,State 中的保存的状态信息允许:

  1. 在 widget 构建时可以被同步读取。
  2. 在 widget 生命周期中可以被改变,当State被改变时,可以手动调用其setState()方法通知Flutter 框架状态发生改变,Flutter 框架在收到消息后,会重新调用其build方法重新构建 widget 树,从而达到更新UI的目的。

State 中有两个常用属性:

  1. widget,它表示与该 State 实例关联的 widget 实例,由Flutter 框架动态设置。
  2. 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对象的几种方法

  1. context对象的findAncestorStateOfType()方法;
    1. ScaffoldState _state = context.findAncestorStateOfType<ScaffoldState>()!;
    2. 直接通过of静态方法来获取State对象:(ScaffoldState _state=Scaffold.of(context);)
  2. 通过GlobalKey
    1. //定义一个globalKey, 由于GlobalKey要保持全局唯一性,我们使用静态变量存储
      static GlobalKey<ScaffoldState> _globalKey= GlobalKey();
      ...
      Scaffold(
          key: _globalKey , //设置key
          ...  
      )
      2. 通过GlobalKey来获取State对象
      _globalKey.currentState.openDrawer()

注意:使用 GlobalKey 开销较大,如果有其他可选方案,应尽量避免使用它。另外,同一个 GlobalKey 在整个 widget 树中必须是唯一的,不能重复。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Flutter·学习实践·UI篇】基础且重要的UI知识 的相关文章

  • Kali Linux 2020 VNC设置自动开机启动

    前提 大家好 目前最新版kali Linux 2020离线包貌似已经取消了桌面安装了 xff0c 需要自己去手动安装桌面 xff0c 所以如果你还是命令行 xff0c 那你就先安装个桌面再说 xff0c 怎么装自己去百度 VNC安装过程 首
  • http://wwwnno00.irrlicht3d.cn:8011/forum-20-3.html

    http wwwnno00 irrlicht3d cn 8011 forum 20 3 html
  • git guest reporter

    权限列表如下 xff1a ActionGuestReporterDeveloperMasterOwnerCreate new issue Leave comments Pull project code Download project C
  • 元素化学期末(考点)整理

    元素化学 期末 xff08 考点 xff09 整理 作者 xff1a gjq 转载或引用需联系作者 xff0c 欢迎给作者打钱 xff01 2019年期末考题请联系作者 xff0c 作者微信 xff1a photon gjq xff0c q
  • 关于ubuntu自启动(rc.local,/etc/rcx.d软连接,创建自定义service)

    ubuntu自启动 xff08 总结 xff09 前言方法一 xff1a 编辑etc rc local方法二 xff1a rcx d 下添加脚本方法三 xff1a 创建service 前言 日常工作中难免碰到需要让某些应用程序自启动的功能
  • springMVC+mybatis环境搭建

    web xml文件配置 lt 加载Spring容器配置 gt lt 设置Spring容器加载所有的配置文件的路径 gt lt context param gt lt param name gt contextConfigLocation l
  • 解决 https 无法访问

    本人腾讯云服务器 xff0c 放假上班打开宝塔面板 xff0c 结果无法访问 我想着重启实例 xff0c 结果面板可以打开 xff0c 但是域名打不开了 xff08 之前是可以打开的 xff09 最后在这个地址找到了答案 xff0c 记录一
  • Python程序设计 简单的图像处理(1)

    Python程序设计 简单的图像处理 xff08 1 xff09 1 写个滤镜 照片照的好 xff0c 不如滤镜用得好 xff01 一款好的滤镜软件可以让照片呈现不一样的风格乃至风情 xff0c 修理照片需要扬长避短达到最佳效果 可是滤镜款
  • Xcode操作流

    1 Xcode IDE概览 说明 xff1a 从左到右 xff0c 依次是 导航窗格 xff08 Navigator xff09 gt 边列 xff08 Gutter xff09 gt 焦点列 xff08 Ribbon xff09 gt 代
  • java gui 多线程,界面假死、僵死问题

    xff08 转载1 xff09 楼主bluepb xff08 流星 xff09 2005 06 04 20 28 17 在 Java GUI 设计 提问 我现在在用jAVA做图形化设计 xff0c 想问个多线程的问题 比如在一个窗口上点个按
  • excel数据对比-----查找两列(表)的相同数据

    原创作品 xff0c 允许转载 xff0c 转载时请务必以超链接形式标明文章 原始出处 作者信息和本声明 否则将追究法律责任 http xueli blog 51cto com 3325186 920592 现有两个excel表 xff0c
  • discuz 微社区 您请求的XXXX无法访问 接口错误(ERR02)

    我遇到的情况 xff1a 1 UC可以访问页面 xff0c 用微信报错 2 4G网络下可以访问 xff0c WiFi网络下报错 网上有两种解决方法 xff1a 1 关闭防采集 xff0c 我最终的采用方法 2 default下的mobile
  • 所有文件夹都变成1KB文件夹快捷方式病毒的手动清除方法

    电脑差不多都因使用U盘而感染了病毒 xff0c 其中一个就是Autoran病毒的变种 xff0c 它的症状我就不再描述了 xff0c 另外一个病毒的症状是所有文件夹都变成了1KB文件夹快捷方式 xff0c 各盘无法双击打开 xff08 但右
  • 搜狗高速浏览器2.0使用体验

    2010年 4 月 8 号 xff0c 我们终于迎来了 国内浏览器的后起之秀搜狗高速浏览器2 0 正式版 的 发布 高速真双核引擎 的概念得到了落实 它新增并改进了诸多功能 xff0c 修改了一些bug xff0c 从整体提高 搜狗高速浏览
  • Connection refused错误

    这个问题整了我两天时间 xff0c 现在终于解决了 问题 xff1a 用php 构造http请求访问自身web服务器页面 xff0c 总是报Connection refused 111 错误 显示 xff1a unable to conne
  • QT样式表从入门到精通

    QT样式表从入门到精通 文章目录 QT样式表从入门到精通前言1 背景介绍2 初级学习2 1 34 盒子 34 模型2 2 语法说明2 3 基础控件2 4 控件状态表2 5 选择器 3 中级学习3 1 坐标讲解3 1 1 相对坐标3 1 2
  • GIF89a图片头文件欺骗

    1 什么是GIF89a 一个GIF89a图形文件就是一个根据图形交换格式 xff08 GIF xff09 89a版 xff08 1989年7 月发行 xff09 进行格式化之后的图形 在GIF89a之前还有87a版 xff08 1987年5
  • txt文件导入mysql

    LOAD DATA LOW PRIORITY CONCURRENT LOCAL INFILE 39 file name 39 REPLACE IGNORE INTO TABLE tbl name CHARACTER SET charset
  • mac下终端无法使用数字小键盘的解决方案

    终端下 偏好设置 xff0d 高级 xff0d xff08 去掉 xff09 允许VT100应用程序小键盘模式
  • Mac Eclipse Failed to load JavaHL Library.

    转自 xff1a http blog csdn net wy10207010219 article details 42294293 写这一篇前我想发表一下感慨 xff1a 你所害怕的事 xff0c 你想要逃避的事 xff0c 在将来的某个

随机推荐