【高心星出品】
文章目录
列表(List)
列表介绍
列表作为一种容器,会自动按其滚动方向排列子组件,向列表中添加组件或从列表中移除组件会重新排列子组件。
List的子组件必须是ListItemGroup或ListItem,ListItem和ListItemGroup必须配合List来使用。
列表布局
List布局方向可以垂直也可以水平,当垂直布局的时候主轴为垂直,可以呈现单列或多列形式;当水平布局的时候主轴为水平,可以呈现单行或多行形式。
主轴为垂直的方向
主轴为水平的方向
设置主轴方向
List组件主轴默认是垂直方向,即默认情况下不需要手动设置List方向,就可以构建一个垂直滚动列表。
若是水平滚动列表场景,将List的listDirection属性设置为Axis.Horizontal即可实现。listDirection默认为Axis.Vertical,即主轴默认是垂直方向。
typescript
List() {
...
}
.listDirection(Axis.Horizontal)
设置交叉轴方向
List组件的交叉轴布局可以通过lanes和alignListItem属性进行设置,lanes属性用于确定交叉轴排列的列表项数量,alignListItem用于设置子组件在交叉轴方向的对齐方式。
List() {
...
}
.lanes(2)
.alignListItem(ListItemAlign.Center)
列表填充
列表填充针对子布局视图和数据源,将数据源中每一条数据初始化给子布局视图ListItem就实现了列表填充。
在日常开发中,我们需要自定义ItemView和创建数据源Datas。
typescript
private contacts = [
new Contact('小明', $r("app.media.iconA")),
new Contact('小红', $r("app.media.iconB")),
...
]
//数据源
build() {
List() {
ForEach(this.contacts, (item: Contact) => { //迭代初始化给listitem
ListItem() {
Row() {
Image(item.icon)
.width(40)
.height(40)
.margin(10)
Text(item.name).fontSize(20)
}
.width('100%')
.justifyContent(FlexAlign.Start)
}
}, item => item.key)
}
.width('100%')
运行效果:
分组列表填充
分组列表填充的时候,数据源在设计的时候要设计标题和该标题对应的数据,在迭代的时候要进行嵌套循环。
typescript
//创建数据源
contactsGroups: object[] = [
{
title: 'A',
contacts: [
new Contact('艾佳', $r('app.media.iconA')),
new Contact('安安', $r('app.media.iconB')),
new Contact('Angela', $r('app.media.iconC')),
],
},
{
title: 'B',
contacts: [
new Contact('白叶', $r('app.media.iconD')),
new Contact('伯明', $r('app.media.iconE')),
],
},
...
]
List() {
// 循环渲染ListItemGroup,contactsGroups为多个分组联系人contacts和标题title的数据集合
ForEach(this.contactsGroups, item => {
ListItemGroup({ header: this.itemHead(item.title) }) {
// 循环渲染ListItem
ForEach(item.contacts, (contact) => {
ListItem() {
...
}
}, item => item.key)
}
...
})
粘性标题
分组填充的时候可以通过sticky设置粘性标题。
typescript
List() {
// 循环渲染ListItemGroup,contactsGroups为多个分组联系人contacts和标题title的数据集合
ForEach(this.contactsGroups, item => {
ListItemGroup({ header: this.itemHead(item.title) }) {
// 循环渲染ListItem
ForEach(item.contacts, (contact) => {
ListItem() {
...
}
}, item => item.key)
}
...
})
}
.sticky(StickyStyle.Header) // 设置吸顶,实现粘性标题效果
}
运行效果为:
滚动条位置
设置滚动位置
List组件初始化时,可以通过scroller参数绑定一个Scroller对象,进行列表的滚动控制。
通过scrollToIndex快速滚动到固定位置。
typescript
private listScroller: Scroller = new Scroller();
Stack({ alignContent: Alignment.BottomEnd }) {
// 将listScroller用于初始化List组件的scroller参数,完成listScroller与列表的绑定。
List({ space: 20, scroller: this.listScroller }) {
...
}
...
Button() {
...
}
.onClick(() => {
// 点击按钮时,指定跳转位置,返回列表顶部
this.listScroller.scrollToIndex(0)
})
...
}
滚到监听
在List滚动的时候,可以通过监听List组件的onScrollIndex事件来获取滚动的索引位置。
可以配合字母表索引组件AlphabetIndexer来实现快速索引。
typescript
Stack({ alignContent: Alignment.End }) {
List({ scroller: this.listScroller }) {
...
}
.onScrollIndex((firstIndex: number) => {
// 根据列表滚动到的索引值,重新计算对应联系人索引栏的位置this.selectedIndex
...
})
...
// 字母表索引组件
AlphabetIndexer({ arrayValue: alphabets, selected: 0 })
.selected(this.selectedIndex)
...
}
}
运行效果为:
列表项侧滑
ListItem列表项可以通过设置swipeAction属性来控制列表项的左右滑动功能。
swipeAction属性方法初始化时有必填参数SwipeActionOptions,其中,start参数表示设置列表项右滑时起始端滑出的组件,end参数表示设置列表项左滑时尾端滑出的组件。
typescript
@Builder itemEnd(index: number) {
// 侧滑后尾端出现的组件
Button({ type: ButtonType.Circle }) {
Image($r('app.media.ic_public_delete_filled'))
.width(20)
.height(20)
}
.onClick(() => {
this.messages.splice(index, 1);
})
...
}
List() {
ForEach(this.messages, (item, index) => {
ListItem() {
...
}
.swipeAction({ end: this.itemEnd.bind(this, index) }) // 设置侧滑属性
}, item => item.id.toString())
}
运行效果为: