flutter listview 滚动到指定位置_Flutter 布局原理及实战

1. Flutter UI架构

a828928b176595f68f6b023b2373348c.png

Flutter将视图数据抽象成为三个部分,即Widget树、Element树和RenderObject树。

  • Widget树:控件的配置信息,不涉及渲染,更新代价极低。
  • RenderObject树:真正的UI渲染树,负责渲染UI,更新代价极大。
  • Element树:Widget树和RenderObject树之间的粘合剂,负责将Widget树的变更以最低的代价映射到RenderObject树上。

2. Flutte布局原理

1. 源码分析

RenderObject是Flutter真正的UI渲染树,负责界面的测量,布局和绘制,Flutter页面布局相关的源码都在RenderObject及其子类中。

34138ce6fb90902ffa6a11550453b3cf.png

上图是RenderObject类中和布局相关的属性和方法.

  • constrainst属性由直接父布局提供的布局约束(最大高度,最小高度,最大宽度,最小宽度),
  • layout方法由父RenderObject调用,计算当前RenderObject的布局,父RenderObject传递给子RenderObject约束信息,子RenderObject必须服从约束信息。如果父RenderObject需要子RenderObject的布局信息,parentUsesSize参数应该传true,否则传false。
  • performLayout:子类必须重写的方法,计算当前RenderObject和子RenderObject的布局信息。
  • performResize:子类必须重写的方法,仅使用约束更新RenderObject的布局。RenderConstrainedBox是ConstrainedBox对应的RenderObject,最多有一个子RenderObject, 如果子RenderoObject不为空,则对子RenderObject进行布局,并计算布局的大小。RenderFlex是Column和Row对应的RenderObject,可以包含多个子RenderObject, 如果子RenderoObject不为空,则对子RenderObject依次进行布局,并计算布局的大小。

2. Flutte布局原理总结

  1. RenderObject会通过它的父级获得自身的约束。 约束实际上就是4个浮点类型的集合:最大/最小宽度,以及最大/最小高度。
  2. 然后,这个RenderObject将会逐个遍历它的children列表。向子级传递约束子级之间的约束可能会有所不同),然后询问它的每一个子级需要用于布局的大小。
  3. 然后,这个RenderObject就会对它子级的children逐个进行布局。(水平方向是x轴,竖直是y轴)
  4. 最后,RenderObject将会把它的大小信息向上传递至父RenderObject(包括其原始约束条件)。

3. Flutter布局限制

由于父RenderObject传递给子RenderObject约束信息,子RenderObject传递给父RenderObject大小信息,Flutter布局存在一些限制:

  • 一个RenderObject仅在其父级给其约束的情况下才能决定自身的大小。 这意味着RenderObject通常情况下不能任意获得其想要的大小。
  • 一个RenderObject无法知道,也不需要决定其在屏幕中的位置。 因为它的位置是由其父级决定的。
  • 当轮到父级决定其大小和位置的时候,同样的也取决于它自身的父级,所以,在不考虑整棵树的情况下,几乎不可能精确定义任何RenderObject的大小和位置。

4. Flutter布局实战

1.线性布局

线性布局的子布局在主轴上长度不能设置无限大(double.infinity),因为线性布局给子布局在主轴上的最大长度的约束就是无限大(double.infinity),会导致无限大的子布局无法计算当前布局的大小,布局失败。如下:

// 第一个子Container的高度设置为无限大,导致布局失败Column(  children: [    Container(      width: 200.0,      height: double.infinity,      color: Colors.blue,    ),    Container(      width: 200.0,      height: 200.0,      color: Colors.red,    ),  ],);// 子Column的高度为无限大,导致布局失败Column(  children: [    Column(      children: [        Container(          width: 200.0,          height: 200.0,          color: Colors.blue,        ),      ],    ),    Container(      width: 200.0,      height: 200.0,      color: Colors.red,    ),  ],);

如果想要让子布局占满全屏可以增加Expanded布局。如下:

Column(  children: [    Expanded(      child: Container(        width: 200.0,        height: double.infinity,        color: Colors.blue,      ),    ),    Container(      width: 200.0,      height: 200.0,      color: Colors.red,    ),  ],);Column(  children: [    Expanded(      child: Column(        children: [          Container(            width: 200.0,            height: 200.0,            color: Colors.blue,          ),        ],      ),    ),    Container(      width: 200.0,      height: 200.0,      color: Colors.red,    ),  ],);

2. 栈布局

栈布局的子布局设置相对位置推荐使用Padding代替Position,并把fit属性设置StackFit.loose,构建时Stack会自适应大小,否则需要使用Container设置Stack和Position的大小;并且Padding默认对上下左右都有相对距离(0),但Position没有默认的相对布局,如果忘记设置,会使Position的子布局无法自动换行或布局不显示。

不推荐:

// Text无法自动换行// Container布局不显示Stack(  children: [    Positioned(      top: 100.0,      child: Text(          '测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试'),    ),    Positioned(      top: 0.0,      child: Column(        children: [          Container(            height: 100.0,            width: double.infinity,            color: Colors.red,          ),        ],      ),    )  ],);

推荐:

Stack(  children: [    Padding(      padding: const EdgeInsets.only(top: 10.0),      child: Text(          '测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试'),    ),    Padding(      padding: const EdgeInsets.only(top: 0.0),      child: Column(        children: [          Container(            height: 100.0,            width: double.infinity,            color: Colors.red,          ),        ],      ),    )  ],);

3. 可滚动布局

可滚动布局在主轴方向上的长度是无限大,父布局需要转递给可滚动布局最大长度的约束。

Column(  children: [    Expanded(      child: ListView(        children: [          Text('测试'),        ],      ),    ),  ],);

横向可滚动布局必须设置高度。

Column(  children: [    Container(      height: 200.0,      child: ListView(        scrollDirection: Axis.horizontal,        children: [          Text('测试'),        ],      ),    ),  ],);

可滚动布局嵌套可滚动布局被嵌套布局的shrinkWrap属性必须设置为true,并且可以将physics属性设置为NeverScrollableScrollPhysics()来解决滑动冲突。

ListView(  children: [    ListView(      shrinkWrap: true,      physics: NeverScrollableScrollPhysics(),      children: [        Text('测试'),      ],    ),  ],);

5. 总结

本文章通过源码分析讲述Flutter布局的过程,分析实战中布局不显示的原因,并给出Flutter布局的一些建议。

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

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

相关文章

雷神开机logo更改_国产外星人雷神再发新品 911MT逐影者RTX2060光追游戏本评测

随着NVIDIA发布了笔记本20系显卡之后,宣示着全民进入了“RTX光线追踪时代”,各种新款的游戏也纷纷宣布支持“光线追踪”技术来吸引更多的玩家,似乎现在游戏本上没有个“RTX”贴纸就已经不好意思跟别人打招呼了。说到2019年的RTX新品&#xff…

AJAX框架衣柜内部布局,​最合理的衣柜内部布局解析,3大细节不容小觑

时常有业主或者朋友问小轻,最合理的衣柜内部布局应该是怎样的,确实这对于非业内人士一般都是不太清楚的,即使有的朋友已经有了丰富的生活经验,甚至是业内人士也不一定对此完全了解。那么到底最合理的衣柜内部布局是怎样的呢&#…

python爬取数据保存为csv时生成编号_将爬取到到数据以CSV格式存储

CSV文件存储 CSV,全称为Comma-Separated Values,中文可以叫做逗号分隔值或字符分隔值,其文件以纯文本形式存储表格数据。该文件是一个字符序列,可以由任意数目的记录组成,记录间以某种换行符分隔。每条记录由字段组成&…

博达3956交换机配置手册_网络设备维保浅谈之交换机维保

随着信息化的飞速发展,交换机作为信息流通的承载者,是应用最为广泛的网络设备之一,其作用不言而喻。因此,在日产使用中,要注意交换机这种核心的设备的维护与保养,以免引发故障。交换机运维需要注意哪些问题…

java cas原理_Java并发之原子变量及CAS算法-上篇

Java并发之原子变量及CAS算法-上篇编辑​概述本文主要讲在Java并发编程的时候,如果保证变量的原子性,在JDK提供的类中是怎么保证变量原子性的呢?。对应Java中的包是:java.util.concurrent.atomic包下。因为涉及到了CAS算法&#x…

node ajax validator,使用validator.js对字符串数据进行验证

validator.js是一个对字符串进行数据验证和过滤的工具库,同时支持Node端和浏览器端,github地址是https://github.com/chriso/validator.js主要API如下:验证APIcontains(str, seed)验证str中是否含有seedequals(str, comparison)验证是否相等i…

css span 右端对齐_CSS标准文档流

web页面的制作,是个“流”,像水流一样,必须从上往下,一点点的编织,不像画画,可以这个地方画一个,另一个地方画一个,随意而为。标准文档流的一些微观现象1. 空白折叠现象1)标签与标签…

composer升级_Composer 使用姿势与 Lumen 升级指南

Composer 使用姿势这里主要说说 composer.json 和 composer.lock 文件的作用。composer.jsoncomposer.json 文件包含了项目的依赖和其它的一些元数据,使用 JSON format 编写。当初次调用 composer install 时,Composer 会根据 composer.json 文件&#x…

服务器间传文件$d,基于OpenSSH+WinSCP完成Windows服务器之间的文件传输

背景经常会遇到在不同服务器之间传输文件,Linux和Linux之间用命令rsync, windows和linux之间普遍是有图形化界面的ftp软件,老黄平时用的比较多的是FileZilla。Windows和Windows之间的话,90%都是在一台机器复制,到另一台…

dbgrideh 为什么只一行_Mysql性能优化:为什么count(*)这么慢?

导读在开发中一定会用到统计一张表的行数,比如一个交易系统,老板会让你每天生成一个报表,这些统计信息少不了sql中的count函数。但是随着记录越来越多,查询的速度会越来越慢,为什么会这样呢?Mysql内部到底是…

jmeter 高并发测试报告_JMeter分布式测试

一、为什么要使用分布式测试按照一般的压力机配置,jmeter的GUI模式下(Windows),最多支持300左右的模拟请求线程,再大的话,容易造成卡顿、无响应等情况,这是限于jmeter其本身的机制和硬件配置。有时候为了尽量模拟业务场…

半圆阴影_六年级数学:怎么求阴影部分面积?正方形与半圆,割补法常考题

欢迎您来到方老师数学课堂,请点击上方蓝色字体,添加关注。所有的视频内容,全部免费,请大家放心关注,放心订阅。六年级数学:怎么求阴影部分面积?正方形与半圆,割补法常考题。大家先在…

c语言判断整数_用c++编写闰年的判断基础程序

其实c语言与c语言有太多共同的东西,学习过c语言再学习c语言就显得轻而易举。当然学过了c再去学习c语言也是有一些帮助的(但是个人不提倡先学习c在学c语言)。由于现在经常看见有关闰年的程序,风式各样,眼花缭乱,些许凌乱&#xff0…

cat日志 搜索_大日志,看我如何对付你

在服务器接口测试中,我们经常会和各种日志打交道。一旦测试时服务端出现了问题,而单凭服务端的日志又不能发现问题原因的时候,往往开发要向我们测试人员询问客户端这边的情况,希望看看我们能不能提供一些有用信息,如错…

加载gif动图_GIF生成神器——ScreenToGif

每次需要做一个动图展示时,总是感觉很头疼。截图吧,需要的图片太多;录视频吧,文件太大;做动图吧,太麻烦。今天推荐的这个软件或许能够解决大家这个困惑,今天推荐的是动图生成神器——ScreenToGi…

java 修改最大nio连接数_关于java流的几个概念:IO、BIO、NIO、AIO,有几个人全知道?...

关于同步、阻塞的知识我之前的文章有介绍,所以关于流用到这些概念与之前多线程用的概念一样。下面具体来看看java中的几种流IO/BIOBIO就是指IO,即传统的Blocking IO,即同步并阻塞的IO。这也是jdk1.4之前的唯一选择,依赖于ServerSocket实现&am…

python扫雷 广度优先_广度优先搜索(BFS)解题总结

定义 广度优先搜索算法(Breadth-First-Search),是一种图形搜索算法。 简单的说,BFS是从根节点开始,沿着树(图)的宽度遍历树(图)的节点。 如果所有节点均被访问,则算法中止。 BFS同样属于盲目搜索。 一般用队…

python裁剪图片并保存_python – 如何从图像中剪切轮廓并将其保存到新文件中

大家好,这是我的第一个问题所以请保持温和.我有一个计算机视觉领域的项目,我是新的,我会很感激一些帮助.我有一个pcb的图像,我的(首先)任务是从背景中切断电路板并将其保存到新文件.如果结果只是没有灰色背景的普通pcb,那就没问题了. 我到目前为止尝试的是,首先使用阈值将图像转…

flash代码_Flash如何对制作文件进行优化

对FLASH进行优化分为两方面,一方面是代码上的优化,主要是通过优化提高FLASH性能,降低CPU占用和内存使用。另一方面是资源的优化,这方面的优化是为了减小编译后的文件大小以及制作文件的大小,因为如果不进行相应的优化&…

deepin系统转为windows_windows系统下安装深度系统deepin

前期准备DiskGenius(用来扩展分区)deepin-20-amd64.iso(深度系统镜像文件)相关文件下载首先下载安装时要用的工具,分别为:DiskGenius , UltraISODiskGenius是一款磁盘工具,创建系统分区。UltraISO是用来打开系统光盘镜像文件工具。Win8/8.1/10无需下载Ul…