189 8069 5689

flutter子组件,flutter子组件重复渲染

Flutter 之 可滚动组件 -- 理论知识点(十四)

Flutter 中有两种布局模型:

成都创新互联专注于仁化企业网站建设,成都响应式网站建设公司,成都商城网站开发。仁化网站建设公司,为仁化等地区提供建站服务。全流程按需网站设计,专业设计,全程项目跟踪,成都创新互联专业和态度为您提供的服务

基于 RenderBox 的盒模型布局。

基于 Sliver ( RenderSliver ) 按需加载列表布局。

通常可滚动组件的子组件可能会非常多、占用的总高度也会非常大;如果要一次性将子组件全部构建出将会非常昂贵!为此,Flutter中提出一个Sliver(中文为“薄片”的意思)概念,Sliver 可以包含一个或多个子组件。Sliver 的主要作用是配合:加载子组件并确定每一个子组件的布局和绘制信息,如果 Sliver 可以包含多个子组件时,通常会实现按需加载模型。

只有当 Sliver 出现在视口中时才会去构建它,这种模型也称为“基于Sliver的列表按需加载模型”。可滚动组件中有很多都支持基于Sliver的按需加载模型,如 ListView 、 GridView ,但是也有不支持该模型的,如 SingleChildScrollView 。

Flutter 中的可滚动主要由三个角色组成: Scrollable 、 Viewport 和 Sliver :

具体布局过程:

比如有一个 ListView,大小撑满屏幕,假设它有 100 个列表项(都是RenderBox)且每个列表项高度相同,结构如图6-1所示:

图中白色区域为设备屏幕,也是 Scrollable 、 Viewport 和 Sliver 所占用的空间,三者所占用的空间重合,父子关系为:Sliver 父组件为 Viewport,Viewport的 父组件为 Scrollable 。注意ListView 中只有一个 Sliver,在 Sliver 中实现了子组件的按需加载。

其中顶部和底部灰色的区域为 cacheExtent,它表示预渲染的高度,需要注意这是在可视区域之外,如果 RenderBox 进入这个区域内,即使它还未显示在屏幕上,也是要先进行构建的,预渲染是为了后面进入 Viewport 的时候更丝滑。cacheExtent 的默认值是 250,在构建可滚动列表时我们可以指定这个值,这个值最终会传给 Viewport。

用于处理滑动手势,确定滑动偏移,滑动偏移变化时构建 Viewport,我们看一下其关键的属性:

在可滚动组件的坐标描述中,通常将滚动方向称为主轴,非滚动方向称为纵轴。由于可滚动组件的默认方向一般都是沿垂直方向,所以默认情况下主轴就是指垂直方向,水平方向同理。

Viewport 比较简单,用于渲染当前视口中需要显示 Sliver。

需要注意的是:

Sliver 主要作用是对子组件进行构建和布局,比如 ListView 的 Sliver 需要实现子组件(列表项)按需加载功能,只有当列表项进入预渲染区域时才会去对它进行构建和布局、渲染。

Sliver 对应的渲染对象类型是 RenderSliver,RenderSliver 和 RenderBox 的相同点是都继承自 RenderObject 类,不同点是在布局的时候约束信息不同。RenderBox 在布局时父组件传递给它的约束信息对应的是 BoxConstraints ,只包含最大宽高的约束;而 RenderSliver 在布局时父组件(列表)传递给它的约束是对应的是 SliverConstraints 。关于 Sliver 的布局协议,我们将在本章最后一节中介绍。

几乎所有的可滚动组件在构造时都能指定 scrollDirection (滑动的主轴)、 reverse (滑动方向是否反向)、 controller 、 physics 、 cacheExtent ,这些属性最终会透传给对应的 Scrollable 和 Viewport,这些属性我们可以认为是可滚动组件的通用属性,后续再介绍具体的可滚动组件时将不再赘述。

可滚动组件都有一个 controller 属性,通过该属性我们可以指定一个 ScrollController 来控制可滚动组件的滚动,比如可以通过ScrollController来同步多个组件的滑动联动。由于 ScrollController 是需要结合可滚动组件一起工作,所以本章中,我们会在介绍完 ListView 后详细介绍 ScrollController。

Scrollbar是一个Material风格的滚动指示器(滚动条),如果要给可滚动组件添加滚动条,只需将Scrollbar作为可滚动组件的任意一个父级组件即可,如:

Scrollbar 和 CupertinoScrollbar 都是通过监听滚动通知来确定滚动条位置的。关于的滚动通知的详细内容我们将在本章最后一节中专门介绍。

CupertinoScrollbar是 iOS 风格的滚动条,如果你使用的是Scrollbar,那么在iOS平台它会自动切换为CupertinoScrollbar

Flutter 布局 - Container详解

Container的组成如下:

- width  和  height :宽和高。

- color :背景色,值为一个 Color 对象,不能与 decoration 属性同时设置。

-  margin :外边距,值为一个 EdgeInsets 对象。EdgeInsets 对象即可调用EdgeInsets.all() 方法统一设置左上右下四条边的边距,也可以调用 EdgeInsets.fromLTRB() 分别设置左上右下四条边的边距。

-  padding :内间距,值同 margin。

-  alignment :元素对齐方式

-  decoration :装饰、背景颜色、边框、背景图片、等,不能与 color 属性同时设置

-  child :子组件

-参数 alignment:

topCenter :顶部居中对齐     topLeft :顶部左对齐      topRight :顶部右对齐      center :水平垂直居中对齐      centerLeft :垂直居中水平居左对齐      centerRight :垂直居中水平居右对齐      bottomCenter 底部居中对齐     bottomLeft :底部居左对齐     bottomRight :底部居右对齐

-参数 decoration :

Container参数的使用如下:

Flutter:手把手教你使用滚动型列表组件:ListView

ListView的基础创建使用有三种方式:

通过默认构造函数来创建列表,应用场景 = 短列表

这种方式创建的列表存在一个问题:对于那些长列表或者需要较昂贵渲染开销的子组件,即使还没有出现在屏幕中但仍然会被ListView所创建,这将是一项较大的开销,使用不当可能引起性能问题甚至卡顿。

长列表

列表子项之间需要分割线

ListView的进阶使用主要包括:下拉刷新 上拉加载

在Flutter中,ListView结合RefreshIndicator组件实现下拉刷新

通过包裹一层RefreshIndicator,自定义onRefresh回调方法实现

方式有两种:

通过ListView.controller属性可以判断ListView是否滑动到了底部,再进行上拉加载

NotificationListener是一个Widget,可监听子Widget发出的Notification

ListView在滑动时中会发出ScrollNotification类型的通知,可通过监听该通知得到ListView的滑动状态,判断是否滑动到了底部,从而进行上拉加载

NotificationListener有一个onNotification属性,定义了监听的回调方法,通过它来处理加载更多逻辑

不定期分享关于 安卓开发 的干货,追求 短、平、快 ,但 却不缺深度 。

Flutter PageView组件怎样让子组件不会重复加载

在做一个美女相册flutter demo app的时候发现,每次切换页面的时候,里面的子页面(GridView widget)每次都会重新加载,就像下面这样:

这样的体验肯定不行。经过一番调研后发现竟然还需要做蛮多事情的。

先看看目前的实现:

这个就是包含在PageView里面的子组件,很简单,通过FutureBuilder调一个接口返回数据后build一个GridView。很显然每次切换Tab的时候,应该是每次都进入了_BeautyListWidgetState的build方法,导致每次都会重新刷新。那要怎样才能做到加载后切换不再刷新呢?

需要实现 wantKeepAlive 方法(返回true),另外在build方法最前面需要 调用 super.build(context); ,如下:

所以你需要在initState方法中创建这个Future。如下:

好了。效果实现了。不过稍后还需要看看AutomaticKeepAliveClientMixin源码,看看它是如何做到的。

Reference:

【Flutter】多组件共用状态,父组件状态传递给子组件

场景:多个组件共用一个状态,子组件通过方法改变父组件状态

思路:状态和管理方法定义在父组件,通过构造函数传递给子组件

其他子组件按照同样方法接收即可共用该父组件的状态。

flutter中如何让Column或Row的子组件相互之间保持一定的间距?

Column或者Row控件的子组件相互之间保持间距的方式有很多种,比较简单直接的实现方式如下:

Column(

children: Widget[

FirstWidget(),

SizedBox(height: 10),//保留间距10

SecondWidget(),

],

),

如果是行的话,参考以下:

Row(

children: Widget[

FirstWidget(),

SizedBox(width: 10),

SecondWidget(),

],

),


网站标题:flutter子组件,flutter子组件重复渲染
文章地址:http://jkwzsj.com/article/dsdhssh.html

其他资讯