• 鸿蒙HarmonyOS开发:List列表组件的使用详解及案例演示


    一、List组件简介

    在我们常用的手机应用中,经常会见到一些数据列表,如设置页面、通讯录、商品列表等。下图中两个页面都包含列表,“首页”页面中包含两个网格布局,“商城”页面中包含一个商品列表。

    列表中都包含一系列相同宽度的列表项,连续、多行呈现同类数据,例如图片和文本。常见的列表有线性列表(List列表)和网格布局(Grid列表)。

    为了帮助开发者构建包含列表的应用,ArkUI提供了List组件和Grid组件,开发者使用List和Grid组件能够很轻松的完成一些列表页面。

    List是很常用的滚动类容器组件,一般和子组件ListItem一起使用,List列表中的每一个列表项对应一个ListItem组件。

    在这里插入图片描述

    1、List组件

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

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

    参数:

    参数名参数类型必填参数描述
    spacenumber、string子组件主轴方向的间隔。
    默认值:0
    说明:
    设置为除-1外其他负数或百分比时,按默认值显示。
    space参数值小于List分割线宽度时,子组件主轴方向的间隔取分割线宽度。
    initialIndexnumber设置当前List初次加载时视口起始位置显示的item的索引值。
    默认值:0
    说明:
    设置为除-1外其他负数或超过了当前List最后一个item的索引值时视为无效取值,无效取值按默认值显示。
    scrollerScroller可滚动组件的控制器。用于与可滚动组件进行绑定。
    说明:
    不允许和其他滚动类组件绑定同一个滚动控制对象。
    2、ListItem组件

    用来展示列表具体item,必须配合List来使用。

    ListItem(value?: string)
    
    • 1

    参数:

    参数名参数类型参数描述
    selectableboolean当前ListItem元素是否可以被鼠标框选。
    说明:
    外层List容器的鼠标框选开启时,ListItem的框选才生效。
    默认值:true
    swipeAction{
    start?: CustomBuilder,
    end?:CustomBuilder,
    edgeEffect?: SwipeEdgeEffect,
    }
    用于设置ListItem的划出组件。
    - start: ListItem向右划动时item左边的组件(List垂直布局时)或ListItem向下划动时item上方的组件(List水平布局时)。
    - end: ListItem向左划动时item右边的组件(List垂直布局时)或ListItem向上划动时item下方的组件(List水平布局时)。
    - edgeEffect: 滑动效果。
    说明:
    start和end对应的@builder函数中顶层必须是单个组件,不能是if/else、ForEach、LazyForEach语句。
    3、ListItemGroup组件

    该组件用来展示列表item分组,宽度默认充满List组件,必须配合List组件来使用。

    当ListItemGroup的父组件List的listDirection属性为Axis.Vertical时,不允许设置ListItemGroup组件的height属性。

    ListItemGroup的高度为header高度、footer高度和所有ListItem布局后总高度之和。当父组件List的listDirection属性为Axis.Horizontal时,不允许设置ListItemGroup组件的width属性。ListItemGroup的宽度为header宽度、footer宽度和所有ListItem布局后总宽度之和。

    当前ListItemGroup内部的ListItem组件不支持编辑、框选、拖拽功能,即ListItem组件的editable、selectable属性不生效。

    ListItemGroup(options?: {header?: CustomBuilder, footer?: CustomBuilder, space?: number | string})
    
    • 1

    参数:

    参数名参数类型必填参数描述
    headerCustomBuilder设置ListItemGroup头部组件。
    footerCustomBuilder设置ListItemGroup尾部组件。
    spacenumber、string列表项间距。只作用于ListItem与ListItem之间,不作用于header与ListItem、footer与ListItem之间。

    说明:

    ListItemGroup组件不支持设置通用属性aspectRatio。
    ListItemGroup组件如果主轴方向是垂直方向时,设置通用属性height属性不生效。
    ListItemGroup组件如果主轴方向是水平方向时,设置通用属性width属性不生效。

    二、使用ForEach渲染列表

    列表往往由多个列表项组成,所以我们需要在List组件中使用多个ListItem组件来构建列表,这就会导致代码的冗余。使用循环渲染(ForEach)遍历数组的方式构建列表,可以减少重复代码。

    在这里插入图片描述

    ForEach接口基于数组类型数据来进行循环渲染,需要与容器组件配合使用,且接口返回的组件应当是允许包含在ForEach父容器组件中的子组件。例如,ListItem组件要求ForEach的父容器组件必须为List组件。

    ForEach(
      arr: Array,
      itemGenerator: (item: Array, index?: number) => void,
      keyGenerator?: (item: Array, index?: number): string => string
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    三、设置列表分割线

    List组件子组件ListItem之间默认是没有分割线的,部分场景子组件ListItem间需要设置分割线,这时候您可以使用List组件的divider属性。divider属性包含四个参数:

    • strokeWidth: 分割线的线宽。
    • color: 分割线的颜色。
    • startMargin:分割线距离列表侧边起始端的距离。
    • endMargin: 分割线距离列表侧边结束端的距离。

    endMargin +startMargin 不能超过列宽度。
    startMargin和endMargin不支持设置百分比。
    List的分割线画在主轴方向两个子组件之间,第一个子组件上方和最后一个子组件下方不会绘制分割线。
    多列模式下,ListItem与ListItem之间的分割线起始边距从每一列的交叉轴方向起始边开始计算,其他情况从List交叉轴方向起始边开始计算。

    四、设置List排列方向

    List组件里面的列表项默认是按垂直方向排列的,如果您想让列表沿水平方向排列,您可以将List组件的listDirection属性设置为Axis.Horizontal。

    listDirection参数类型是Axis,定义了以下两种类型:

    • Vertical(默认值):子组件ListItem在List容器组件中呈纵向排列。
    • Horizontal:子组件ListItem在List容器组件中呈横向排列。

    在这里插入图片描述
    在这里插入图片描述

    五、索引值计算规则

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

    • 按子组件的顺序依次递增。
    • if/else语句中,只有条件成立的分支内的子组件会参与索引值计算,条件不成立的分支内子组件不计算索引值。
    • ForEach/LazyForEach语句中,会计算展开所有子节点索引值。
    • if/else/ForEach/LazyForEach发生变化以后,会更新子节点索引值。
    • ListItemGroup作为一个整体计算一个索引值,ListItemGroup内部的ListItem不计算索引值。
    • List子组件的visibility属性设置为Hidden或None依然会计算索引值。
    • List子组件的visibility属性设置为None时不显示,但该子组件上下的space还会生效。

    六、示例演示

    List组件结合AlphabetIndexer实现汽车之家选车页面布局

    1、AlphabetIndexer组件

    可以与容器组件联动用于按逻辑结构快速定位容器显示区域的组件。

    AlphabetIndexer(value: {arrayValue: Array, selected: number})
    
    • 1

    参数:

    参数名参数类型必填参数描述
    arrayValueArray字母索引字符串数组,不可设置为空。
    selectednumber初始选中项索引值,若超出索引值范围,则取默认值0。
    2、代码
    const alphabets = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
      'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
    
    interface CarItemInterface {
      title: string
    }
    
    interface CarInterface {
      alphabet: string,
      carItem: CarItemInterface[]
    }
    
    @Entry
    @Component
    struct CarListIndex {
      @State selectedIndex: number = 0
      private listScroller: Scroller = new Scroller()
      @State carList: CarInterface[] = [{
        alphabet: "A",
        carItem: [
          {
            title: "奥迪"
          },
          {
            title: "奥拓"
          },
          {
            title: "爱驰"
          },
          {
            title: "ATS"
          },
          {
            title: "AIM"
          },
          {
            title: "阿尔特"
          },
        ]
      },
        {
          alphabet: "B",
          carItem: [
            {
              title: "奔驰"
            },
            {
              title: "比亚迪"
            },
            {
              title: "宝马"
            },
            {
              title: "保时捷"
            },
            {
              title: "北京"
            },
            {
              title: "标致"
            },
          ]
        },
        {
          alphabet: "C",
          carItem: [
            {
              title: "长安"
            },
            {
              title: "长城"
            },
            {
              title: "曹操汽车"
            },
            {
              title: "成功汽车"
            },
            {
              title: "北京"
            },
            {
              title: "标致"
            },
          ]
        },
        {
          alphabet: "D",
          carItem: [
            {
              title: "大众"
            },
            {
              title: "东风"
            },
            {
              title: "Ds"
            },
            {
              title: "大运"
            },
            {
              title: "东南"
            },
            {
              title: "大帝"
            },
          ]
        },
        {
          alphabet: "E",
          carItem: [
            {
              title: "e.GO"
            },
            {
              title: "Elek"
            },
          ]
        },
        {
          alphabet: "F",
          carItem: [
            {
              title: "丰田"
            },
            {
              title: "福特"
            },
            {
              title: "福田"
            },
            {
              title: "法拉利"
            },
            {
              title: "福地"
            },
            {
              title: "菲亚特"
            },
          ]
        }
      ]
    
      //自定义组件内自定义构建函数
      @Builder itemHead(text: string) {
        Text(text)
          .fontSize(20)
          .backgroundColor(0xEEEEEE)
          .width("100%")
          .padding(10)
      }
    
      build() {
        Column() {
          Stack({ alignContent: Alignment.End }) {
            Column() {
              List({ scroller: this.listScroller }) {
                ForEach(this.carList, (item: CarInterface) => {
                  ListItemGroup({ header: this.itemHead(item.alphabet) }) {
                    ForEach(item.carItem, (pro: CarItemInterface) => {
                      ListItem() {
                        Text(pro.title)
                          .fontSize(16)
                          .padding(10)
                          .width("100%")
                      }
                    })
                  }
                })
              }
              .onScrollIndex((index: number) => {
                this.selectedIndex = index
              })
              .sticky(StickyStyle.Header)
            }.height('100%')
            .width('100%')
    
            AlphabetIndexer({ arrayValue: alphabets, selected: 0 })
              .selected(this.selectedIndex)
              .onSelect((index) => {
                this.listScroller.scrollToIndex(index)
              })
          }
        }
        .width('100%')
        .height('100%')
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    3、效果

    在这里插入图片描述

  • 相关阅读:
    js逆向之浏览器环境补充
    【CodeForces】CF13C Sequence(配数学证明)
    Unity Xlua热更新框架(二):构建AssetBundle
    【精华】ROS学习(二):Realsense ROS驱动安装
    php加密解密
    半回文数【Python】
    强大的音频制作软件 Logic Pro X 最新中文 for mac
    Ubuntu 搭建小熊派 hi3861 环境
    中国“互联网+”大学生创新创业大赛“的实施方案及评审规则
    SQL 的执行流程是什么样的
  • 原文地址:https://blog.csdn.net/shanghai597/article/details/138605234