概述
列表是一种复杂的容器,当列表项达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能。它适合用于呈现同类数据类型或数据类型集,例如图片和文本。在列表中显示数据集合是许多应用程序中的常见要求(如通讯录、音乐列表、购物清单等)。
使用列表可以轻松高效地显示结构化、可滚动的信息。通过在 List 组件中按垂直或者水平方向线性排列子组件 ListItemGroup ,为列表中的行或列提供单个视图,或使用 循环渲染 迭代一组行或列,或混合任意数量的单个视图和ForEach结构,构建一个列表。List组件支持使用条件渲染、循环渲染、懒加载等 渲染控制 方式生成子组件。
布局与约束
列表作为一种容器,会自动按其滚动方向排列子组件,向列表中添加组件或从列表中移除组件会重新排列子组件。
如下图所示,在垂直列表中,List按垂直方向自动排列ListItemGroup或ListItem。
ListItemGroup用于列表数据的分组展示,其子组件也是ListItem。ListItem表示单个列表项,可以包含单个子组件。
图1 List、ListItemGroup和ListItem组件关系
说明
List的子组件必须是ListItemGroup或ListItem,ListItem和ListItemGroup必须配合List来使用。
布局
List除了提供垂直和水平布局能力、超出屏幕时可以滚动的自适应 延伸能力 之外,还提供了自适应交叉轴方向上排列个数的布局能力。
利用垂直布局能力可以构建单列或者多列垂直滚动列表,如下图所示。
图2 垂直滚动列表(左:单列;右:多列)
利用水平布局能力可以是构建单行或多行水平滚动列表,如下图所示。
图3 水平滚动列表(左:单行;右:多行)
Grid和WaterFlow也可以实现单列、多列布局,如果布局每列等宽,且不需要跨行跨列布局,相比Gird和WaterFlow,则更推荐使用List。
约束
列表的主轴方向是指子组件列的排列方向,也是列表的滚动方向。垂直于主轴的轴称为交叉轴,其方向与主轴方向相互垂直。
如下图所示,垂直列表的主轴是垂直方向,交叉轴是水平方向;水平列表的主轴是水平方向,交叉轴是垂直方向。
图4 列表的主轴与交叉轴
如果List组件主轴或交叉轴方向设置了尺寸,则其对应方向上的尺寸为设置值。
如果List组件主轴方向没有设置尺寸,当List子组件主轴方向总尺寸小于List的父组件尺寸时,List主轴方向尺寸自动适应子组件的总尺寸。
如下图所示,一个垂直列表B没有设置高度时,其父组件A高度为200vp,若其所有子组件C的高度总和为150vp,则此时列表B的高度为150vp。
图5 列表主轴高度约束示例1(A: List的父组件; B: List组件; C: List的所有子组件)
如果子组件主轴方向总尺寸超过List父组件尺寸时,List主轴方向尺寸适应List的父组件尺寸。
如下图所示,同样是没有设置高度的垂直列表B,其父组件A高度为200vp,若其所有子组件C的高度总和为300vp,则此时列表B的高度为200vp。
图6 列表主轴高度约束示例2(A: List的父组件; B: List组件; C: List的所有子组件)
List组件交叉轴方向在没有设置尺寸时,其尺寸默认自适应父组件尺寸。
开发布局
设置主轴方向
List组件主轴默认是垂直方向,即默认情况下不需要手动设置List方向,就可以构建一个垂直滚动列表。
若是水平滚动列表场景,将List的listDirection属性设置为Axis.Horizontal即可实现。listDirection默认为Axis.Vertical,即主轴默认是垂直方向。
List() {
// ...
}
.listDirection(Axis.Horizontal)
设置交叉轴布局
List组件的交叉轴布局可以通过lanes和alignListItem属性进行设置,lanes属性用于确定交叉轴排列的列表项数量,alignListItem用于设置子组件在交叉轴方向的对齐方式。
List组件的lanes属性通常用于在不同尺寸的设备自适应构建不同行数或列数的列表,即一次开发、多端部署的场景,例如 歌单列表 。lanes属性的取值类型是"number | LengthConstrain ",即整数或者LengthConstrain类型。以垂直列表为例,如果将lanes属性设为2,表示构建的是一个两列的垂直列表,如图2中右图所示。lanes的默认值为1,即默认情况下,垂直列表的列数是1。
List() {
// ...
}
.lanes(2)
当其取值为LengthConstrain类型时,表示会根据LengthConstrain与List组件的尺寸自适应决定行或列数。
@Entry
@Component
struct EgLanes {
@State egLanes: LengthConstrain = { minLength: 200, maxLength: 300 }
build() {
List() {
// ...
}
.lanes(this.egLanes)
}
}
例如,假设在垂直列表中设置了lanes的值为{ minLength: 200, maxLength: 300 }。此时,
-
当List组件宽度为300vp时,由于minLength为200vp,此时列表为一列。
-
当List组件宽度变化至400vp时,符合两倍的minLength,则此时列表自适应为两列。
同样以垂直列表为例,当alignListItem属性设置为ListItemAlign.Center表示列表项在水平方向上居中对齐。alignListItem的默认值是ListItemAlign.Start,即列表项在列表交叉轴方向上默认按首部对齐。
List() {
// ...
}
.alignListItem(ListItemAlign.Center)
在列表中显示数据
列表视图垂直或水平显示项目集合,在行或列超出屏幕时提供滚动功能,使其适合显示大型数据集合。在最简单的列表形式中,List静态地创建其列表项ListItem的内容。
图7 城市列表
@Entry
@Component
struct CityList {
build() {
List() {
ListItem() {
Text('北京').fontSize(24)
}
ListItem() {
Text('杭州').fontSize(24)
}
ListItem() {
Text('上海').fontSize(24)
}
}
.backgroundColor('#FFF1F3F5')
.alignListItem(ListItemAlign.Center)
}
}
由于在ListItem中只能有一个根节点组件,不支持以平铺形式使用多个组件。因此,若列表项是由多个组件元素组成的,则需要将这多个元素组合到一个容器组件内或组成一个自定义组件。
图8 联系人列表项示例
如上图所示,联系人列表的列表项中,每个联系人都有头像和名称。此时,需要将Image和Text封装到一个Row容器内。
List() {
ListItem() {
Row() {
Image($r('app.media.iconE'))
.width(40)
.height(40)
.margin(10)
Text('小明')
.fontSize(20)
}
}
ListItem() {
Row() {
Image($r('app.media.iconF'))
.width(40)
.height(40)
.margin(10)
Text('小红')
.fontSize(20)
}
}
}
迭代列表内容
通常,应用通过数据集合动态地创建列表。使用 循环渲染 可从数据源中迭代获取数据,并在每次迭代过程中创建相应的组件,降低代码复杂度。
ArkTS通过 ForEac