列表(List)
List列表组件是最常用的容器器组件之一,当列表项达到一定数量,内容超过列表尺寸大小时,可以自动提供滚动功能。使用列表可以轻松高效地显示结构化、可滚动的信息。
创建列表
List列表中的每一个列表项用ListItem来表示,List必须嵌套ListItem一起使用。
如下图所示,这是一个简单的列表,每一个列表项显示一个文本。
代码如下,其中.divider()属性用于给列表项设置分割线。
@Entry
@Component
struct Index {
build() {
Column() {
List({ space: 10 }) {
ListItem(){
Text('0').width("100%").height(100).textAlign(TextAlign.Center)
}
ListItem(){
Text('1').width("100%").height(100).textAlign(TextAlign.Center)
}
ListItem(){
Text('2').width("100%").height(100).textAlign(TextAlign.Center)
}
ListItem(){
Text('3').width("100%").height(100).textAlign(TextAlign.Center)
}
ListItem(){
Text('4').width("100%").height(100).textAlign(TextAlign.Center)
}
ListItem(){
Text('5').width("100%").height(100).textAlign(TextAlign.Center)
}
ListItem(){
Text('6').width("100%").height(100).textAlign(TextAlign.Center)
}
ListItem(){
Text('7').width("100%").height(100).textAlign(TextAlign.Center)
}
ListItem(){
Text('8').width("100%").height(100).textAlign(TextAlign.Center)
}
ListItem(){
Text('9').width("100%").height(100).textAlign(TextAlign.Center)
}
ListItem(){
Text('10').width("100%").height(100).textAlign(TextAlign.Center)
}
}.divider({
strokeWidth: 1,
color: "#dedede",
startMargin: 10,
endMargin: 10
})
}.width("100%")
.height("100%")
}
}
列表样式
- 通过{ space: 10 }参数用来设置列表项之间的间距;
List({ space: 10 }) {
// …
}
- 通过.divider()属性用来设置列表项之间的分割线;
List() {
// …
}
.divider({
strokeWidth: 0.5,//分割线的粗细
color:Color.Black//分割线的颜色
})
- 通过.scrollBar()属性用来设置滚动条的显示模式;
List() {
// …
}
.scrollBar(BarState.Auto) //默认不显示,滚动时显示,2秒后消失
- 通过.listDirection() 属性设置列表滚动方向
List() {
// …
}
.listDirection(Axis.Horizontal)
循环渲染
一般情况下List列表项的UI结构都是相同的,可以采用ForEach循环渲染所有列表项。
ForEach有如下特点
-
List组件创建时,所有ListItem将会被创建。
-
显示区域内的ListItem在首帧进行布局,预加载范围内的ListItem在空闲时完成布局。预加载范围之外的ListItem仅创建ListItem自身,ListItem其内部的子组件不会被创建。
-
当List组件滑动时,进入预加载及显示区域的ListItem将会创建其内部的子组件并完成布局,而滑出预加载及显示区域的ListItem将不会被销毁。
代码如下
@Entry
@Component
struct Index {
@State array: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
build() {
Column() {
List({ space: 10 }) {
ForEach(this.array,(item:number)=>{
ListItem(){
Text(`${item}`).width("100%").height(100).textAlign(TextAlign.Center)
}
})
}.divider({
strokeWidth: 1,
color: "#dedede",
startMargin: 10,
endMargin: 10
})
}.width("100%")
.height("100%")
}
}
复杂列表
当列表项的UI结构较为复杂时,建议采用@Builder装饰器对UI组件进行封装以实现复用,同时将列表数据封装为独立的对象模型,从而实现UI展示与数据逻辑的彻底解耦。
class Product{
image:ResourceStr = '' //图片
title:string = '' //标题
salesVolume:number = 0 //销售数量
price:number = 0 //价格
constructor(image: ResourceStr, title: string, salesVolume: number, price: number) {
this.image = image
this.title = title
this.salesVolume = salesVolume
this.price = price
}
}
@Entry
@Component
struct Index {
@State array:Product[] = [
new Product($r('app.media.11'),"漫花无芯卷纸16卷*1提",1000,9.9),
new Product($r('app.media.22'),"BuBBLE TREE 款式",200,19.9),
new Product($r('app.media.33'),"爸爸妈妈器材风车玩具",100,7.9),
new Product($r('app.media.44'),"曼花挂式洗脸巾50抽*3提",500,19.9)
]
build() {
Column() {
List({space:10}){
ForEach(this.array,(item:Product)=>{
ListItem(){
this.productListItem(item)
}
})
}.padding(10)
}.width("100%")
.height("100%")
.backgroundColor("#dedede")
}
@Builder
productListItem(item: Product) {
Row({ space: 10 }) {
Image(item.image).width(100).height(100)
.borderRadius(10)
Column() {
Text(item.title).fontSize(16)
Text(item.salesVolume + "+售出").fontSize(12).fontColor(Color.Orange)
Text("¥" + item.price + "元").fontWeight(FontWeight.Bold).fontSize(18).fontColor(Color.Red)
}.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
}
.width("100%")
.justifyContent(FlexAlign.Start)
.alignItems(VerticalAlign.Center)
.padding(10)
.backgroundColor(Color.White)
.borderRadius(10)
}
}
编辑列表
编辑列表指的是新增、删除、更新列表项,这是对于列表常见的操作之一。下面以待办事项管理为例,介绍如何快速实现新增和删除列表项功能。
代码如下
//@ObservedV2
@ObservedV2
class ToDo {
name: string = '' //标题
@Trace isCompleted: boolean = false //是否完成
constructor(name: string, isCompleted?: boolean) {
this.name = name
this.isCompleted = isCompleted ?? false
}
}
@Entry
@Component
struct Index {
@State todoList: ToDo[] = [
new ToDo("运动"),
new ToDo("阅读")
]
//代办选中的样式
toDoCompletedStyle: DecorationStyleInterface = {
type: TextDecorationType.LineThrough,
color: Color.Red
}
build() {
Column() {
List({ space: 10 }) {
ForEach(this.todoList, (item: ToDo, index: number) => {
ListItem() {
this.toDoListItem(item, index)
}
})
}.padding(10)
Button("添加代办")
.onClick(() => {
this.todoList.push(new ToDo("新任务"))
})
}.width("100%")
.height("100%")
.backgroundColor("#dedede")
}
@Builder
toDoListItem(item: ToDo, index: number) {
Row({ space: 10 }) {
Checkbox().onChange((value: boolean) => {
item.isCompleted = value
})
Text(item.name).fontSize(16).fontWeight(FontWeight.Bold)
.decoration(item.isCompleted ? this.toDoCompletedStyle : undefined)
Blank()
Text('删除')
.fontColor("#00aaff")
.fontSize(14)
.fontWeight(FontWeight.Bold)
.onClick(() => {
//从当前位置删除一个元素
this.todoList.splice(index, 1)
})
}
.width("100%")
.height(50)
.backgroundColor(item.isCompleted ? Color.Pink : Color.White)
.borderRadius(15)
.padding({ left: 10, right: 10 })
}
}
鸿蒙开发者认证 未完待续…
评论前必须登录!
注册