HarmonyOs-ArkUI List组件

news2025/5/14 18:25:34

列表是一个复杂的容器,当列表项达到一定数量,使得列表内容超出其范围的时候,就会自动变为可以滚动。列表适合用来展现同类数据类型。

List组件支持使用,条件渲染,循环渲染,懒加载等渲染控制方式生成子组件。

List的布局与约束

List提供垂直方向或者水平方向的布局能力,当其内容超出List本身最大的范围后,其字内容便会可以滚动,初次之外,List还提供了交叉轴方向上自适应排列个数布局的能力。

例如一个纵向的List,可以有一列,同时也可以有多列。

一个横向的List,一般有一行,但是也可以存在多行

以上布局,事实上Grid和WaterFlow两种布局都可以达到,但是如果一个布局的子组件每一个列,宽,长宽全部一致。这里推荐用List。 如果需要每个子组件长宽不一致甚至是随机自适应等情况则才考虑使用Grid 或者 WaterFlow。

约束

指的是List组件的长宽约束。一般是,如果List没有指定大小的情况下,List的长宽规则是,子组件是否能撑到List布局的极限, 到了极限, 也就是list没有指定大小,但是List的父组件已经确定大小了,或者通过父组件计算出List只能撑到某一个大小了。 这种情况下, list中子组件少到不足以撑开的时候,list的大小就是子组件合起来的大小,当子组件的量大了,大到list最大值的时候,List到最大就不变了,内容变为可滚动。

List的基本使用方法

List组件的构建声明是这个样子的

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

参数详解:

  • space: 代表子项中挨着的间距。
  • initiallIndex: 代表首次进列表的时候初始滑动的位置,单位按照索引来进行测算。自动滑动的位置为 置顶第一个。
  • scroller: 可滚动组件控制器(所以不止一个组件欧)。 如果一个List有滑动控制的需求,例如点击某一个按钮就会向上移动多少,此时,没有办法直接拿到List的对象去滑动,而是通过滑动控制器绑定完进行控制。

initiallIndex使用案例:

@State list:string[] = ['1', '2', '3', '4', '5', '6', '7']
build() {
  ...
  List({space: 8, initiallIndex: 3}){
    ForEach(this.list, (item: string) => {
      ....
    }, (item: string) => item)
  }
}

可滚动组件控制器-Scroller

上方我们讲了下List组件构建的时候所需要的参数,其余两个,space, 和 initiallIndex都比较好理解,我们不做赘述。 下面讲讲第三个参数Scroller。

Scroller就是用来控制可滚动组件的滚动行为的。List也是一种可滚动组件,也支持了这个控制器。

Scroller初始化

非常简单,new一下即可。

// 1 初始化对象
scroller: Scroller = new Scroller()

// 2 使用对象
build() {
  ...
  List({space: 8, initiallIndex: 3, scroller: this.scroller}){
    ForEach(this.list, (item: string) => {
      ....
    }, (item: string) => item)
  }
}

Scroller功能

  • scrollTo :滑动到指定位置
  • scrollEdge: 滑动到边缘
  • scrollBy:滑动指定距离

// 1 初始化对象
scroller: Scroller = new Scroller()

// 2 使用对象
build() {
  ...
  List({space: 8, initiallIndex: 3, scroller: this.scroller}){
    ForEach(this.list, (item: string) => {
      ....
    }, (item: string) => item)
  }

  Button('scroll 50')
  .onclick(()=>{
    this.scroller.scrollBy(0, 50)
  })

  Button('back top')
  .onclick(()=>{
    this.scroller.scrollEdge(Edge.Top)
  })
}

List属性

属性

功能

listDirection

设置List组件排列方向

lanes

设置List组件行数或者列数

divider

设置ListItem分割线样式

scrollBar

设置滚动条状态

alignListItem

设置Item对齐方式,有时候List的每一个项远远大于Item组件的大小,此时就需要对齐了

sticky

指定ListItemGroup什么部分作为粘性标题

swipeAction

指定侧滑方式

listDirection属性-设置列表方向

用于设置List组件的内容排列方向。 其值为一个枚举:

  • Axis.Vertical 纵向
  • Axis.Horizontal 横向
// 1 初始化对象
scroller: Scroller = new Scroller()

// 2 使用对象
build() {
  ...
  List({space: 8, initiallIndex: 3, scroller: this.scroller}){
    ForEach(this.list, (item: string) => {
      ....
    }, (item: string) => item)
  }
  .listDirection(Axis.Vertical)
}

lanes属性-设置列数

lanes是车道,划分区域的意思。这个属性设置的时候参数比较复杂。我们看看原型。

lanes(value: number|LengthConstrain, gutter?: Dimension)

  • value: 设置列表内容的列数或者行数。这个行数可以为number用于指定是什么列,也可以为LengthConstrain类型,用于指定,每一个列的最小值和最大值,使得根据父容器大小,来动态度的计算应该需要几列。
  • gutter: 设置列间距。 此处的列间距,应该变通理解,如果一个表目前是横向的,那么它只有一个横向的”列“!
// 1 初始化对象
scroller: Scroller = new Scroller()

// 2 使用对象
build() {
  ...
  List({space: 8, initiallIndex: 3, scroller: this.scroller}){
    ForEach(this.list, (item: string) => {
      ....
    }, (item: string) => item)
  }
  .listDirection(Axis.Vertical)
  .lanes(2)
}

List是纵向的,出现了两列

value为LengthConstrain类型时的使用方式
// 1 初始化对象
scroller: Scroller = new Scroller()
// 目标就是使得列表排列的好看,假如宽为300, 则会有一列, 假如宽为400,则两列正好,也符合最小
// 标准,就会展示两列
@State lenthConstrains: LengthConstrains = {minLength: 200, maxLength: 300}

// 2 使用对象
build() {
  ...
  List({space: 8, initiallIndex: 3, scroller: this.scroller}){
    ForEach(this.list, (item: string) => {
      ....
    }, (item: string) => item)
  }
  .listDirection(Axis.Vertical)
  .lanes(this.lenthConstrains)
}

divider属性-设置分割线样式

// 1 初始化对象
scroller: Scroller = new Scroller()

// 2 使用对象
build() {
  ...
  List({space: 8, initiallIndex: 3, scroller: this.scroller}){
    ForEach(this.list, (item: string) => {
      ....
    }, (item: string) => item)
  }
  .listDirection(Axis.Vertical)
  .lanes(2)
  .divider({
    strockWidth: 2,
    color: '#4472c4',
    startMargin: 20,
    endMargin: 20
  })
}

scrollBar属性-设置滚动条状态

这个比较好理解就不做代码展示了。我们理解下参数的意义即可。

scrollBar(barState: BarState)

BarState枚举说明

  • Auto:按需展示,触摸时展示,2秒后就消失。
  • Off:不展示
  • On:常驻展示、

List,ListItemGroup, ListItem 组件关系

ListItemGroup用于列表数据的分组展示,其组件也是ListItem。ListItem表示单个列表项,可以包含单个组件。

list(){
  listItemGroup(){
    listItem(){...}
  }

  listItemGroup(){
    listItem(){...}
    listItem(){...}
  }

  listItemGroup(){
    listItem(){...}
    listItem(){...}
  }
}

粘性标题分组列表

分组列表不好解释,但是我们看一张图就明白其中的意思了

首先,我们要实现分组的效果,之后再加粘性标题,如果如右侧图片,在右侧栏加上导航,可以再加一个额外的组件做。有现成的组件,当然也可以自己写。

1 首先分组

可以用ListItemGroup来做这件事情,ListItemGroup本身支持加一些header的,我们可以把分组做成header。

@Builder itemHeader(title: string){
  // 列表分组的头部组件,对应联系人分组A、B等位置的组件
    Text(text)
      .fontSize(20)
      .backgroundColor('#fff1f3f5')
      .width('100%')
      .padding(5)
}

build() {
  List() {
      ListItemGroup({ header: this.itemHeader('A') }) {
        // 循环渲染分组A的ListItem
      }

      ListItemGroup({ header: this.itemHeader('B') }) {
        // 循环渲染分组B的ListItem
      }
    }
}

当然这是较为低级的写法,通常我们会列好数据结构,用ForEach层层循环渲染即可。

2 添加粘性标题

粘性标题也是我们生活中经常用到的一种交互方式。

如下图所示,在联系人列表中滚动A部分时,B部分开始的头部元素始终处于A的下方。而在开始滚动B部分时,B的头部会固定在屏幕顶部,直到所有B的项均完成滚动后,才被后面的头部替代。

List为我们提供了这种交互,解决方式是:sticky属性,这个属性是用来配合ListItemGroup来使用的。使用起来非常简单。

@Builder itemHeader(title: string){
  // 列表分组的头部组件,对应联系人分组A、B等位置的组件
    Text(text)
      .fontSize(20)
      .backgroundColor('#fff1f3f5')
      .width('100%')
      .padding(5)
}

build() {
  List() {
      ListItemGroup({ header: this.itemHeader('A') }) {
        // 循环渲染分组A的ListItem
      }

      ListItemGroup({ header: this.itemHeader('B') }) {
        // 循环渲染分组B的ListItem
      }
    }
}.sticky(StickyStyle.Header)

如果需要底吸功能需要

  • 初始化ListItemGroup的Footer
  • 将sticky绑定为StickyStyle.Footer

3 响应滚动位置

控制滚动位置

如果想要完成类似于字母导航的功能,则首先需要回顾一下,滚动到指定位置的方式。前面已经讲解过,我们可以在List声明的时候就设置一个参数,为Scroller。 可以通过调用Scroller的一些方法来让列表滑动到指定的位置。响应滚动位置在一定程度上用到了这里的原理。Scroller里面记录了一个位置数据,这个数据实际上是可以被观察的,同时它也是遵循双向绑定的。

响应滚动位置改变导航,与点击导航跳转到指定位置

HarmonyOs ArkUI为我们提供了一个组件AlphabetIndexer,用来展示一个右侧的索引栏。这里面实现的时候有个有意思的点就是, AlphabetIndexer内部存了一个双向绑定的参数,List中记录的参数衔接上,那么,当List参数变得时候,AlphabetIndexer参数自然会变动,界面也会变动。 当AlphabetIndexer内部检测到用户选择了某个选项,自然也会通过改动这个值, 从而List列表位置自然也变更了。

const alphabels = ['#', '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']

@Entry
@Component
struct ConstractList{
    @State selectedIndex: number = 0
    private listController: Scroller = new Scroller()
    build() {
      Stack({ alignContent: Alignment.End }) {
        List({ scroller: this.listScroller }) {}
        .onScrollIndex((firstIndex: number) => {
          // 根据列表滚动到的索引值,重新计算对应联系人索引栏的位置this.selectedIndex
        })
  
        // 字母表索引组件
        AlphabetIndexer({ arrayValue: alphabets, selected: 0 })
          .selected(this.selectedIndex)
      }
  }
}

响应列表侧滑

我们可以用List的 swipeAction属性去实现列表的侧滑功能,其参数为 SwipeActionOptions来指定是从哪里侧滑。

我们注意到列表项目被侧滑之后,会出现一个删除的按钮,这个按钮是从哪里设置的呢? 实际上,这个swipeAction与我们之前的提到的粘性标题使用方式有异曲同工之处

  • 1 需要指定List框架特定的,已经成为概念的,某界面的内容。 在此处,就是List中已经协议好的,尾端滑出组件,其使用环节位于,ListItem中。
  • 2 仅仅需要设置swipeAction参数就行了。
// 找指定的区域,设置布局
@Builder itemEnd(index: number) {
   // 构建尾端滑出组件
  Button({ type: ButtonType.Circle }) {
    Image($r('app.media.ic_public_delete_filled'))
      .width(20)
      .height(20)
  }
  .onClick(() => {
    // this.messages为列表数据源,可根据实际场景构造。点击后从数据源删除指定数据项。
    this.messages.splice(index, 1);
  })
}
ForEach(list, (item: string, index: number)=>{
  ListItem(){
    //此处省略很多布局内容
  }
  .swipeAction( // 参数是一个SwipeActionOptions, 可以分别指定滑动方向,以及滑动后需要build的界面行为
    {end: {builder: ()=> this.itemEnd(index)}}
  )
}, (item: string)=> item.toString)

列表辅助红点逻辑控件-Badge

在应用的开发中,红点逻辑必不可少,比如聊天消息,通知等等。几乎大型的App都需要。正常情况下我们自己写控件也可以实现,但是,ArkUI给我们提供好了这种控件,就比较省事了。 控件名字叫 Badge。使用方法比较简单,看看基本就懂了。

ListItem() {
  Badge({
    count: 1,
    position: BadgePosition.RightTop,
    style: {badgeSize: 16, badgeColor: '#FA2A2D'}
  }) {
    // Image组件实现消息联系人头像
    // ...
  }
}

数据懒加载

循环列表,适用于短列表,当构建具有大量列表项的长列表时, 如果直接采用循环引用的方式,会使得一次性加载所有的元素,会导致页面启动时间过长,影响用户体验,此时,推荐使用数据懒加载LazyForEach方式按需加载数据,从而提升列表性能。

当使用LazyForEach进行加载时,可以指定列表项的缓存数量

List(){
  ...
}
// 如果是含有ListItemGroup,那么缓存数量就是以group为单位。
// 如果列表是多列的,那么数量就会乘列数。总不能不展示全是不是?
.cachedCount(3) 
  • cachesCount的数量如果设置的太高,会增大UI对CPU的占用,内存开销也会变大,使用时要根据真实情况来定。
  • 列表数据使用懒加载的时候,除了显示界面内的以及前后缓存的列表项数量,其余的列表项是会被销毁的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2322974.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于YOLOv8深度学习的PCB缺陷检测识别系统【python源码+GUI界面+数据集+训练代码+登录界面】

目录 一、界面全貌展示 二、前言摘要 三、GUI界面演示 (一)用户加载自定义模型 (二)单张图像检测 (三)检测图像文件夹 (四)检测视频 (五)摄像头检测 …

鸿蒙生态圈暗战:数字孪生三强争霸谁将主宰消费电子未来?

IDC数据显示,2025年Q1华为以38.7%份额领跑中国折叠屏市场,Pura X首月销量突破120万台。这款搭载HarmonyOS 5的旗舰,通过灵犀通信技术实现5G A网络下载速率提升30%,并在离线环境下完成厘米级导航。其爆款逻辑背后,是鸿蒙…

react 15-16-17-18各版本的核心区别、底层原理及演进逻辑的深度解析

一、React 15(2016) 核心架构:Stack Reconciler(栈协调器) 工作原理: 同步递归渲染:采用深度优先遍历方式递归处理 Virtual DOM,形成不可中断的调用栈渲染流程:1. 触发 …

CMS迁移中SEO优化整合步骤详解

内容概要 在CMS迁移过程中,系统化的规划与执行是保障SEO排名稳定性的核心。首先需明确迁移流程的关键阶段,包括数据备份、URL适配、元数据同步及安全配置等环节。其中,数据备份不仅需覆盖原始数据库与静态资源,还需验证备份文件的…

数据结构初阶-二叉树链式

目录 1.概念与结构 2.二叉数链式的实现 2.1遍历规则 2.2申请内存空间 2.3手动构建一棵二叉树 2.4二叉树结点的个数 2.5二叉树叶子结点的个数 2.6二叉树第K层结点个数 2.7二叉树的高度 2.8二叉树中查找值为x的结点 2.9二叉树的销毁 3.层序遍历 3.1概念 3.2层序遍历…

Springboot 集成 Flowable 6.8.0

1. 创建 Spring Boot 项目 通过 Spring Initializr(https://start.spring.io/ )创建一个基础的 Spring Boot 项目,添加以下依赖: Spring WebSpring Data JPAMySQL DriverLombok(可选,用于简化代码&#x…

协作机械臂需要加安全墙吗? 安全墙 光栅 干涉区

安全墙是什么 文章目录 安全墙是什么简介1. 物理安全墙1.1 定义:1.2 作用机制:1.3 应用场景: 2. 虚拟安全墙2.2 定义:2.3 作用机制:2.3 应用场景: 3. 安全毛毯3.1 工作原理:3.2 特点3.3 应用场景…

springboot+mybatisplus

1.什么是springboot? Spring Boot是一个用于快速构建Spring应用程序的框架。它旨在帮助开发人员快速搭建Spring框架,减少配置和繁琐的工作。Spring Boot继承了原有Spring框架的优秀基因,使Spring在使用中更加方便快捷。 在Spring Boot中集成ActiveMQ,需要导入相应的starter…

《TypeScript 面试八股:高频考点与核心知识点详解》

“你好啊!能把那天没唱的歌再唱给我听吗? ” 前言 因为主包还是主要学习js,ts浅浅的学习了一下,在简历中我也只会写了解,所以我写一些比较基础的八股,如果是想要更深入的八股的话还是建议找别人的。 Ts基…

SICAR 标准 KUKA 机器人标准功能块说明手册

功能块名称:LSicar_Robot_KUKA_PrD 目录 1. 概述 2. 功能说明 2.1 程序控制 2.2 状态监控 2.3 报警与故障处理 2.4 驱动控制 3. 关键参数说明 4. 操作步骤指南 4.1 初始化配置 4.2 运行控制 4.3 状态监控 5. 常见故障处理 6. 注意事项 附录1:程序段索引 附录…

linux中如何修改文件的权限和拥有者所属组

目录标题 chmod指令八进制形式权限修改文件拥有者所属组的修改umask有关内容 chmod指令 chmod指令可以用来修改人员的权限其形式如下: u代表的是拥有者,g代表的是所属组,o代表的是其他人,a表示所有人,如果你想增加权…

掌握Linux项目自动化构建:从零入门make与Makefile

文章目录 前言: 一、初识自动化构建工具1.1 什么是make/Makefile?1.2 快速体验 二、深入理解核心机制2.1 依赖关系与依赖方法2.2 伪目标的妙用2.3 具体语法a.makefile的基本雏形b.makefile推导原则! 三、更加具有通用型的makefile1. 变量定义…

Jenkins 配置python项目和allure

Jenkins新建项目 新建ry-api-auto-test。 添加项目描述,选择gitee令牌。 源码管理,设置仓库地址和凭证。参考我上一篇文章的链接:配置gitee私人令牌和凭证 构建步骤,因为我Jenkins部署在Windows,因此选择batch。…

vue3:十一、主页面布局(进入指定菜单页面,默认锁定到左侧菜单)

一、效果 直接进入home页面,直接展开对应的菜单项 二、具体实现 1、菜单容器增加默认选中变量 在菜单容器中将默认展开菜单default-openeds修改为默认选中菜单default-active 2、引入useRoute方法 引入该方法为了获取当前页面的路径 import { useRoute } from …

【蓝桥杯】每日练习 Day13

前言 今天做了不少题,但是感觉都太水了,深思熟虑之下主播决定拿出两道相对不那么水的题来说一下(其实还是很水)。 两道问题,一道是日期问题(模拟),一道是区间合并问题。 日期差值 …

【Docker系列七】Docker Compose 命令详解

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【AI学习】Transformer 模型

1,概念 是一种基于自注意力机制(Self-Attention Mechanism)的深度学习架构,在自然语言处理、计算机视觉等多个领域都有着极为重要的应用。 2,基本结构 1)编码器(Encoder) 通常由多个相同的编码器层堆叠而成。 每个编码器层包含了多头自注意力机制、前馈神经网络以及…

大数据学习栈记——HBase操作(shell java)

本文介绍HBase在shell终端的常见操作以及如何利用java api操作HBase,操作系统:Ubuntu24.04 参考: https://blog.51cto.com/u_16099228/8016429 https://blog.csdn.net/m0_37739193/article/details/73618899 https://cloud.tencent.com/d…

智能制造:物联网和自动化之间的关系

工业自动化 工业自动化是机器设备或生产过程在不需要人工直接干预的情况下按预期的目标实现测量、操纵等信息处理和过程控制的统称。 在传统的工业生产过程中,很多环节需要人工操作,比如设备调试、生产监控、质量检测等。然而,随着工业自动化…

Axure项目实战:智慧城市APP(三)教育查询(显示与隐藏交互)

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 课程主题:教育查询 主要内容:教育公告信息,小升初、初升高、高考成绩查询;教育公告信息为传统的信息页面,小升…