List

列表包含一系列相同宽度的列表项。适合连续、多行呈现同类数据,例如图片和文本。

说明:

  • 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
  • 该组件内容区小于一屏时,默认没有回弹效果。需要回弹效果,可以通过edgeEffect属性的options参数进行设置。

子组件

仅支持ListItemListItemGroup子组件。

说明:

List的子组件的索引值计算规则:

按子组件的顺序依次递增。

if/else语句中,只有条件成立的分支内的子组件会参与索引值计算,条件不成立的分支内子组件不计算索引值。

ForEach/LazyForEach语句中,会计算展开所有子节点索引值。

if/elseForEachLazyForEach发生变化以后,会更新子节点索引值。

ListItemGroup作为一个整体计算一个索引值,ListItemGroup内部的ListItem不计算索引值。

List子组件visibility属性设置为Hidden或None依然会计算索引值。

List子组件的visibility属性设置为None时不显示,但该子组件上下的space还会生效。

接口

List(value?:{space?: number | string, initialIndex?: number, scroller?: Scroller})

从API version 9开始,该接口支持在ArkTS卡片中使用。

参数:

参数名 参数类型 必填 参数描述
space number | string 子组件主轴方向的间隔。
默认值:0
参数类型为number时单位为vp
说明:
设置为负数或者大于等于List内容区长度时,按默认值显示。
space参数值小于List分割线宽度时,子组件主轴方向的间隔取分割线宽度。
initialIndex number 设置当前List初次加载时视口起始位置显示的item的索引值。
默认值:0
说明:
设置为负数或超过了当前List最后一个item的索引值时视为无效取值,无效取值按默认值显示。
scroller Scroller 可滚动组件的控制器。用于与可滚动组件进行绑定。
说明:
不允许和其他滚动类组件绑定同一个滚动控制对象。

属性

除支持通用属性外,还支持以下属性:

名称 参数类型 描述
listDirection Axis 设置List组件排列方向。
默认值:Axis.Vertical
从API version 9开始,该接口支持在ArkTS卡片中使用。
divider {
strokeWidth: Length,
color?:ResourceColor,
startMargin?: Length,
endMargin?: Length
} | null
设置ListItem分割线样式,默认无分割线。
- strokeWidth: 分割线的线宽。
- color: 分割线的颜色。
- startMargin: 分割线与列表侧边起始端的距离。
- endMargin: 分割线与列表侧边结束端的距离。
从API version 9开始,该接口支持在ArkTS卡片中使用。
endMargin + startMargin 超过列宽度后startMargin和endMargin会置0。
strokeWidth, startMargin和endMargin不支持设置百分比。
List的分割线画在主轴方向两个子组件之间,第一个子组件上方和最后一个子组件下方不会绘制分割线。
多列模式下,ListItem与ListItem之间的分割线起始边距从每一列的交叉轴方向起始边开始计算,其他情况从List交叉轴方向起始边开始计算。
scrollBar BarState 设置滚动条状态。
默认值:BarState.Off
从API version 9开始,该接口支持在ArkTS卡片中使用。
说明:
API version 9及以下版本默认值为BarState.Off,API version 10的默认值为BarState.Auto。
cachedCount number 设置列表中ListItem/ListItemGroup的预加载数量,只在LazyForEach中生效,其中ListItemGroup将作为一个整体进行计算,ListItemGroup中的所有ListItem会一次性全部加载出来。具体使用可参考减少应用白块说明
默认值:1
从API version 9开始,该接口支持在ArkTS卡片中使用。
说明:
单列模式下,会在List显示的ListItem前后各缓存cachedCount个ListItem。
多列模式下, 会在List显示的ListItem前后各缓存cachedCount*列数个ListItem。
editMode(deprecated) boolean 声明当前List组件是否处于可编辑模式。
从API version9开始废弃不再使用,无替代接口。
可参考示例3实现删除选中的list项。
默认值:false
edgeEffect EdgeEffect 设置组件的滑动效果,支持弹簧效果和阴影效果。
默认值:EdgeEffect.Spring
从API version 9开始,该接口支持在ArkTS卡片中使用。
chainAnimation boolean 设置当前List是否启用链式联动动效,开启后列表滑动以及顶部和底部拖拽时会有链式联动的效果。链式联动效果:List内的list-item间隔一定距离,在基本的滑动交互行为下,主动对象驱动从动对象进行联动,驱动效果遵循弹簧物理动效。
默认值:false
- false:不启用链式联动。
- true:启用链式联动。
从API version 9开始,该接口支持在ArkTS卡片中使用。
说明:
链式动效生效后,List的分割线不显示。
链式动效生效需要满足以下前提条件:
-  List边缘效果为Spring类型
-  List没有启用多列模式
chainAnimationOptions10+ ChainAnimationOptions 设置链式联动动效参数。
系统API: 此接口为系统接口。
multiSelectable8+ boolean 是否开启鼠标框选。
默认值:false
- false:关闭框选。
- true:开启框选。
从API version 9开始,该接口支持在ArkTS卡片中使用。
lanes9+ number | LengthConstrain,
gutter10+?:Dimension
以列模式为例(listDirection为Axis.Vertical):
lanes用于决定List组件在交叉轴方向按几列布局。
默认值:1
规则如下:
- lanes为指定的数量时,根据指定的数量与List组件的交叉轴尺寸除以列数作为列的宽度。
- lanes设置了{minLength,maxLength}时,根据List组件的宽度自适应决定lanes数量(即列数),保证缩放过程中lane的宽度符合{minLength,maxLength}的限制。其中,minLength条件会被优先满足,即优先保证符合ListItem的交叉轴尺寸符合最小限制。
- lanes设置了{minLength,maxLength},如果父组件交叉轴方向尺寸约束为无穷大时,固定按一列排列,列宽度按显示区域内最大的ListItem计算
- ListItemGroup在多列模式下也是独占一行,ListItemGroup中的ListItem按照List组件的lanes属性设置值来布局。
- lanes设置了{minLength,maxLength}时,计算列数会按照ListItemGroup的交叉轴尺寸计算。当ListItemGroup交叉轴尺寸与List交叉轴尺寸不一致时ListItemGroup中的列数与List中的列数可能不一样。
gutter为列间距,当列数大于1时生效。
默认值为 0
该接口支持在ArkTS卡片中使用。
alignListItem9+ ListItemAlign List交叉轴方向宽度大于ListItem交叉轴宽度 * lanes时,ListItem在List交叉轴方向的布局方式,默认为首部对齐。
默认值:ListItemAlign.Start
该接口支持在ArkTS卡片中使用。
sticky9+ StickyStyle 配合ListItemGroup组件使用,设置ListItemGroup中header和footer是否要吸顶或吸底。
默认值:StickyStyle.None
该接口支持在ArkTS卡片中使用。
说明:
sticky属性可以设置为 StickyStyle.Header | StickyStyle.Footer 以同时支持header吸顶和footer吸底。
scrollSnapAlign10+ ScrollSnapAlign 设置列表项滚动结束对齐效果。
默认值:ScrollSnapAlign.NONE
说明:
只支持ListItem等高情况下,设置列表项滚动结束对齐效果。
触控板和鼠标滑动List结束后不支持对齐效果。
enableScrollInteraction10+ boolean 设置是否支持滚动手势,当设置为false时,无法通过手指或者鼠标滚动,但不影响控制器的滚动接口。
默认值:true
nestedScroll10+ NestedScrollOptions 嵌套滚动选项。设置向前向后两个方向上的嵌套滚动模式,实现与父组件的滚动联动。
friction10+ number | Resource 设置摩擦系数,手动划动滚动区域时生效,只对惯性滚动过程有影响,对惯性滚动过程中的链式效果有间接影响。
默认值:非可穿戴设备为0.6,可穿戴设备为0.9
说明:
设置为小于等于0的值时,按默认值处理

ListItemAlign9+枚举说明

该接口支持在ArkTS卡片中使用。

名称 枚举值 描述
Start 0 ListItem在List中,交叉轴方向首部对齐。
Center 1 ListItem在List中,交叉轴方向居中对齐。
End 2 ListItem在List中,交叉轴方向尾部对齐。

StickyStyle9+枚举说明

该接口支持在ArkTS卡片中使用。

名称 枚举值 描述
None 0 ListItemGroup的header不吸顶,footer不吸底。
Header 1 ListItemGroup的header吸顶,footer不吸底。
Footer 2 ListItemGroup的footer吸底,header不吸顶。

ChainEdgeEffect10+枚举说明

设置链式动效边缘效果。

系统API: 此接口为系统接口

名称 枚举值 描述
DEFAULT 0 默认效果,列表滚动到边缘以后继续拖动,拖拽方向上的列表项间距缩小,
拖拽反方向上的列表项间距扩大。
STRETCH 1 列表滚动到边缘以后继续拖动,所有列表项间距扩大。

chainAnimationOptions10+对象说明

链式联动动效属性集合,用于设置List最大间距、最小间距、动效强度、传导系数和边缘效果。

系统API: 此接口为系统接口

名称 类型 必填 说明
minSpace Length 设置链式联动动效最小间距。
maxSpace Length 设置链式联动动效最大间距。
conductivity number 设置链式联动动效传导系数。取值范围[0,1],数值越大,动效传导范围越远。
默认为0.7。
intensity number 设置链式联动动效效果强度。取值范围[0,1],数值越大,动效效果越明显。
默认为0.3。
edgeEffect ChainEdgeEffect 设置链式联动动效边缘效果。
默认为ChainEdgeEffect.DEFAULT。

说明:

List组件通用属性clip的默认值为true。

ScrollSnapAlign10+枚举说明

设置列表项滚动结束对齐效果。

从API version 10开始,该接口支持在ArkTS卡片中使用。

左右和上下这种两端对齐的样式:当列表位移至末端,则需要将末端的item完整显示,同时不能露出边界空白区域,此时另一端可以出现不限位对齐的现象。

只支持item等高场景限位,不等高场景可能存在不准确的情况。

名称 枚举值 描述
NONE 0 默认无项目滚动对齐效果。
START 1 视图中的第一项将在列表的开头对齐。
说明:
当列表位移至末端,需要将末端的item完整显示,可能出现开头不对齐的情况。
CENTER 2 视图中的中间项将在列表中心对齐。
说明:
顶端和末尾的item都可以在列表中心对齐,列表显示可能露出空白,
第一个或最后一个item会对齐到中间位置。
END 3 视图中的最后一项将在列表末尾对齐。
说明:
当列表位移至顶端,需要将顶端的item完整显示,可能出现末尾不对齐的情况。

事件

名称 功能描述
onItemDelete(deprecated)(event: (index: number) => boolean) 当List组件在编辑模式时,点击ListItem右边出现的删除按钮时触发。
从API version9开始废弃不再使用,无替代接口。
- index: 被删除的列表项的索引值。
onScroll(event: (scrollOffset: number, scrollState: ScrollState) => void) 列表滑动时触发。
- scrollOffset: 每帧滚动的偏移量,List的内容向上滚动时偏移量为正,向下滚动时偏移量为负,单位vp。
- scrollState: 当前滑动状态。
从API version 9开始,该接口支持在ArkTS卡片中使用。
onScrollIndex(event: (start: number, end: number, center10+: number) => void) 有子组件划入或划出List显示区域时触发。从API version 10开始,List显示区域中间位置子组件变化时也会触发。
计算索引值时,ListItemGroup作为一个整体占一个索引值,不计算ListItemGroup内部ListItem的索引值。
- start: List显示区域内第一个子组件的索引值。
- end: List显示区域内最后一个子组件的索引值。
- center: List显示区域内中间位置子组件的索引值。
触发该事件的条件:列表初始化时会触发一次,List显示区域内第一个子组件的索引值或最后一个子组件的索引值有变化时会触发。从API version 10开始,List显示区域中间位置子组件变化时也会触发。
List的边缘效果为弹簧效果时,在List划动到边缘继续划动和松手回弹过程不会触发onScrollIndex事件。
从API version 9开始,该接口支持在ArkTS卡片中使用。
onReachStart(event: () => void) 列表到达起始位置时触发。
从API version 9开始,该接口支持在ArkTS卡片中使用。
说明:
List初始化时如果initialIndex为0会触发一次,List滚动到起始位置时触发一次。List边缘效果为弹簧效果时,划动经过起始位置时触发一次,回弹回起始位置时再触发一次。
onReachEnd(event: () => void) 列表到底末尾位置时触发。
从API version 9开始,该接口支持在ArkTS卡片中使用。
说明:
List边缘效果为弹簧效果时,划动经过末尾位置时触发一次,回弹回末尾位置时再触发一次。
onScrollFrameBegin9+(event: (offset: number, state: ScrollState) => { offsetRemain:number }) 列表开始滑动时触发,事件参数传入即将发生的滑动量,事件处理函数中可根据应用场景计算实际需要的滑动量并作为事件处理函数的返回值返回,列表将按照返回值的实际滑动量进行滑动。
- offset:即将发生的滑动量,单位vp。
- state:当前滑动状态。
- offsetRemain:实际滑动量,单位vp。
触发该事件的条件:手指拖动List、List惯性划动时每帧开始时触发;List超出边缘回弹、使用滚动控制器和拖动滚动条的滚动不会触发。
该接口支持在ArkTS卡片中使用。
说明:
当listDirection的值为Axis.Vertical时,返回垂直方向滑动量,当listDirection的值为Axis.Horizontal时,返回水平方向滑动量。
onScrollStart9+(event: () => void) 列表滑动开始时触发。手指拖动列表或列表的滚动条触发的滑动开始时,会触发该事件。使用Scroller滑动控制器触发的带动画的滑动,动画开始时会触发该事件。
该接口支持在ArkTS卡片中使用。
onScrollStop(event: () => void) 列表滑动停止时触发。手拖动列表或列表的滚动条触发的滑动,手离开屏幕并且滑动停止时会触发该事件;使用Scroller滑动控制器触发的带动画的滑动,动画停止会触发该事件。
从API version 9开始,该接口支持在ArkTS卡片中使用。
onItemMove(event: (from: number, to: number) => boolean) 列表元素发生移动时触发。
- from: 移动前索引值。
- to: 移动后索引值。
onItemDragStart8+(event: (event: ItemDragInfo, itemIndex: number) => ((() => any) | void) 开始拖拽列表元素时触发。
- event: 见ItemDragInfo对象说明
- itemIndex: 被拖拽列表元素索引值。
onItemDragEnter8+(event: (event: ItemDragInfo) => void) 拖拽进入列表元素范围内时触发。
- event: 见ItemDragInfo对象说明
onItemDragMove8+(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number) => void) 拖拽在列表元素范围内移动时触发。
- event: 见ItemDragInfo对象说明
- itemIndex: 拖拽起始位置。
- insertIndex: 拖拽插入位置。
onItemDragLeave8+(event: (event: ItemDragInfo, itemIndex: number) => void) 拖拽离开列表元素时触发。
- event: 见ItemDragInfo对象说明
- itemIndex: 拖拽离开的列表元素索引值。
onItemDrop8+(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => void) 绑定该事件的列表元素可作为拖拽释放目标,当在列表元素内停止拖拽时触发。
- event: 见ItemDragInfo对象说明
- itemIndex: 拖拽起始位置。
- insertIndex: 拖拽插入位置。
- isSuccess: 是否成功释放。
说明:
跨List拖拽时,当拖拽释放的位置绑定了onItemDrop时会返回true,否则为false。List内部拖拽时,isSuccess为onItemMove事件的返回值。

ScrollState枚举说明

从API version 9开始,该接口支持在ArkTS卡片中使用。

名称 枚举值 描述
Idle 0 空闲状态。使用控制器提供的方法控制滚动时触发,拖动滚动条滚动时触发。
说明:
从API version 10开始,调整为滚动状态回归空闲时触发,
控制器提供的无动画方法控制滚动时触发。
Scroll 1 滚动状态。使用手指拖动List滚动时触发。
说明:
从API version 10开始,拖动滚动条滚动和滚动鼠标滚轮时也会触发。
Fling 2 惯性滚动状态。快速划动松手后进行惯性滚动和划动到边缘回弹时触发。
说明:
从API version 10开始,由动画控制的滚动都触发。包括快速划动松手后的惯性滚动,
划动到边缘回弹的滚动,快速拖动内置滚动条松手后的惯性滚动,
使用滚动控制器提供的带动画的方法控制的滚动。

ScrollState枚举变更如下。

场景 API version 9及以下 API version 10开始
手指拖动滑动 Scroll Scroll
惯性滚动 Fling Fling
过界回弹 Fling Fling
鼠标滚轮滚动 Idle Scroll
拖动滚动条 Idle Scroll
滚动控制器滚动(带动画) Idle Fling
滚动控制器滚动(不带动画) Idle Idle

说明:

要使List处于可编辑模式需配合onItemDelete事件和ListItem的editable属性,即可编辑模式实现删除列表项功能,需满足以下条件(该功能从API9开始废弃):

  • editMode属性设置为true。

  • 绑定onItemDelete事件,且事件回调返回true。

  • ListItem的editable属性设置为true。

实现ListItem拖拽,需满足以下条件:

  • editMode属性设置为true(从API9开始无需设置editMode属性)。

  • 绑定onDragStart事件,且事件回调中返回浮动UI布局。

示例

示例1

// xxx.ets
@Entry
@Component
struct ListExample {
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

  build() {
    Column() {
      List({ space: 20, initialIndex: 0 }) {
        ForEach(this.arr, (item: number) => {
          ListItem() {
            Text('' + item)
              .width('100%').height(100).fontSize(16)
              .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
          }
        }, (item: string) => item)
      }
      .listDirection(Axis.Vertical) // 排列方向
      .scrollBar(BarState.Off)
      .friction(0.6)
      .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
      .edgeEffect(EdgeEffect.Spring) // 边缘效果设置为Spring
      .onScrollIndex((firstIndex: number, lastIndex: number, centerIndex: number) => {
        console.info('first' + firstIndex)
        console.info('last' + lastIndex)
        console.info('center' + centerIndex)
      })
      .onScroll((scrollOffset: number, scrollState: ScrollState) => {
        console.info(`onScroll scrollState = ScrollState` + scrollState + `, scrollOffset = ` + scrollOffset)
      })
      .width('90%')
    }
    .width('100%')
    .height('100%')
    .backgroundColor(0xDCDCDC)
    .padding({ top: 5 })
  }
}

zh-cn_image_0000001174264378

示例2

// xxx.ets
@Entry
@Component
struct ListLanesExample {
  @State arr: string[] = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"]
  @State alignListItem: ListItemAlign = ListItemAlign.Start

  build() {
    Column() {
      List({ space: 20, initialIndex: 0 }) {
        ForEach(this.arr, (item: string) => {
          ListItem() {
            Text('' + item)
              .width('100%')
              .height(100)
              .fontSize(16)
              .textAlign(TextAlign.Center)
              .borderRadius(10)
              .backgroundColor(0xFFFFFF)
          }
          .border({ width: 2, color: Color.Green })
        }, (item: string) => item)
      }
      .height(300)
      .width("90%")
      .friction(0.6)
      .border({ width: 3, color: Color.Red })
      .lanes({ minLength: 40, maxLength: 40 })
      .alignListItem(this.alignListItem)
      .scrollBar(BarState.Off)

      Button("点击更改alignListItem:" + this.alignListItem).onClick(() => {
        if (this.alignListItem == ListItemAlign.Start) {
          this.alignListItem = ListItemAlign.Center
        } else if (this.alignListItem == ListItemAlign.Center) {
          this.alignListItem = ListItemAlign.End
        } else {
          this.alignListItem = ListItemAlign.Start
        }
      })
    }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
  }
}

list

示例3

// xxx.ets
@Entry
@Component
struct ListExample {
  @State arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  @State editFlag: boolean = false

  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Column() {
        List({ space: 20, initialIndex: 0 }) {
          ForEach(this.arr, (item: number, index?: number) => {
            ListItem() {
              Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
                Text('' + item)
                  .width('100%')
                  .height(80)
                  .fontSize(20)
                  .textAlign(TextAlign.Center)
                  .borderRadius(10)
                  .backgroundColor(0xFFFFFF)
                  .flexShrink(1)
                if (this.editFlag) {
                  Button() {
                    Text("delete").fontSize(16)
                  }.width('30%').height(40)
                  .onClick(() => {
                    if (index != undefined) {
                      console.info(this.arr[index] + 'Delete')
                      this.arr.splice(index, 1)
                      console.info(JSON.stringify(this.arr))
                      this.editFlag = false
                    }
                  }).stateEffect(true)
                }
              }
            }
          }, (item: string) => item)
        }.width('90%')
        .scrollBar(BarState.Off)
        .friction(0.6)
      }.width('100%')

      Button('edit list')
        .onClick(() => {
          this.editFlag = !this.editFlag
        }).margin({ top: 5, left: 20 })
    }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
  }
}

list

示例4

// xxx.ets
@Entry
@Component
struct ListExample {
  private arr: number[] = []
  private scrollerForList: Scroller = new Scroller()

  aboutToAppear() {
    for (let i = 0; i < 20; i++) {
      this.arr.push(i)
    }
  }
  build() {
    Column() {
      Row() {
        List({ space: 20, initialIndex: 3, scroller: this.scrollerForList }) {
          ForEach(this.arr, (item: number) => {
            ListItem() {
              Text('' + item)
                .width('100%').height(100).fontSize(16)
                .textAlign(TextAlign.Center)
            }
            .borderRadius(10).backgroundColor(0xFFFFFF)
            .width('60%')
            .height('80%')
          }, (item: number) => JSON.stringify(item))
        }
        .chainAnimation(true)
        .edgeEffect(EdgeEffect.Spring)
        .listDirection(Axis.Horizontal)
        .height('100%')
        .width('100%')
        .scrollSnapAlign(ScrollSnapAlign.CENTER)
        .borderRadius(10)
        .backgroundColor(0xDCDCDC)
      }
      .width('100%')
      .height('100%')
      .backgroundColor(0xDCDCDC)
      .padding({ top: 10 })
    }
  }
}

list