当前位置: 首页 > news >正文

2.7、创建列表(List)

概述

列表是一种复杂的容器,当列表项达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能。它适合用于呈现同类数据类型或数据类型集,例如图片和文本。在列表中显示数据集合是许多应用程序中的常见要求(如通讯录、音乐列表、购物清单等)。

使用列表可以轻松高效地显示结构化、可滚动的信息。通过在List组件中按垂直或者水平方向线性排列子组件ListItemGroup或ListItem,为列表中的行或列提供单个视图,或使用ForEach迭代一组行或列,或混合任意数量的单个视图和ForEach结构,构建一个列表。List组件支持使用条件渲染、循环渲染、懒加载等渲染控制方式生成子组件。

我开发的 Demo 展示

在这里插入图片描述

以下代码均经过我 demo 的实战验证,确保代码和效果对应

布局与约束

列表作为一种容器,会自动按其滚动方向排列子组件,向列表中添加组件或从列表中移除组件会重新排列子组件。

如下图所示,在垂直列表中,List按垂直方向自动排列ListItemGroup或ListItem。

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

布局

List除了提供垂直和水平布局能力、超出屏幕时可以滚动的自适应延伸能力之外,还提供了自适应交叉轴方向上排列个数的布局能力。

利用垂直布局能力可以构建单列或者多列垂直滚动列表,如下图所示。

垂直滚动列表

  • 单列
    在这里插入图片描述
    对应代码
@Entry
@Component
struct ListVerticalPage {@State listItems:Array<String> = []aboutToAppear() {for (var i =0;i< 50;i++) {this.listItems.push("")}}build() {Navigation() {List({space: 5}) {ForEach(this.listItems, ()=> {ListItem() {Stack().width('100%').height(100).backgroundColor('#9dc3e6')}.padding({left:15, right:15})})}}.title('垂直滚动列表').titleMode(NavigationTitleMode.Mini)}
}
  • 多列
    在这里插入图片描述
@Entry
@Component
struct ListMultiVerticalPage {@State listItems:Array<String> = []aboutToAppear() {for (var i =0;i< 50;i++) {this.listItems.push("")}}build() {Navigation() {List({space: 5}) {ForEach(this.listItems, ()=> {ListItem() {Stack().width('100%').height(100).backgroundColor('#9dc3e6')}.padding({left:2,right:2})})}.lanes(2)}.title('垂直滚动多列').titleMode(NavigationTitleMode.Mini)}
}

水平滚动列表

  • 单列
    在这里插入图片描述
    对应代码
@Entry
@Component
struct ListHorizontalPage {@State listItems:Array<String> = []aboutToAppear() {for (var i =0;i< 50;i++) {this.listItems.push(`${i+1}`)}}build() {Navigation() {List({space: 5}) {ForEach(this.listItems, (item:string)=> {ListItem() {Text(item).textAlign(TextAlign.Center).width(50).height(300).backgroundColor('#9dc3e6')}})}.listDirection(Axis.Horizontal)}.title('水平滚动列表').titleMode(NavigationTitleMode.Mini)}
}
  • 多列
    在这里插入图片描述
    对应代码
@Entry
@Component
struct ListMultiHorizontalPage {@State listItems:Array<String> = []aboutToAppear() {for (var i =0;i< 50;i++) {this.listItems.push(`${i+1}`)}}build() {Navigation() {List({space: 5}) {ForEach(this.listItems, (item:string)=> {ListItem() {Text(item).textAlign(TextAlign.Center).width(50).height(300).backgroundColor('#9dc3e6')}})}.lanes(2).listDirection(Axis.Horizontal)}.title('水平滚动多列').titleMode(NavigationTitleMode.Mini)}
}

自定义列表样式

设置内容间距

在初始化列表时,如需在列表项之间添加间距,可以使用 space 参数。例如,在每个列表项之间沿主轴方向添加 55vp 的间距:

在这里插入图片描述

对应局部代码

List({space: 55}) {ForEach(this.listItems, ()=> {ListItem() {Stack().width('100%').height(100).backgroundColor('#9dc3e6')}})
}

添加分隔线

效果图
在这里插入图片描述
对应代码

List() {ForEach(this.listItems, ()=> {ListItem() {Stack().width('100%').height(100).backgroundColor('#9dc3e6')}})
}
.divider({strokeWidth: 1,startMargin: 60,endMargin: 10,color: '#ff0000'
})

添加滚动条

效果图
在这里插入图片描述
对应代码

List() {ForEach(this.listItems, ()=> {ListItem() {Stack().width('100%').height(100).backgroundColor('#9dc3e6')}})
}
.scrollBar(BarState.Auto)
.divider({strokeWidth: 1,color: '#ff0000'
})

支持分组列表

在列表中支持数据的分组展示,可以使列表显示结构清晰,查找方便,从而提高使用效率。分组列表在实际应用中十分常见,如下图所示联系人列表。

在这里插入图片描述
对应代码

import router from '@ohos.router'
import { CodeView } from '../../../widget/CodeView'interface ContactGroup {title:stringcontacts:Array<String>
}@Entry
@Component
struct GroupListPage {contactsGroups: ContactGroup[] = [{title: 'A',contacts: ["安以轩","安悦溪",        ],},{title: 'B',contacts: ["白敬亭","白宇",       ],},...}]@Builder itemHead(text: string) {// 列表分组的头部组件,对应联系人分组A、B等位置的组件Text(text).fontSize(20).width('100%').padding(10).backgroundColor('#ffffff').fontWeight(FontWeight.Bold)}@Builder itemContent(text: string) {// 列表分组的头部组件,对应联系人分组A、B等位置的组件Text(text).padding({ left: 10, bottom: 10, top: 10 })}build() {Navigation() {List() {ForEach(this.contactsGroups, (item:ContactGroup)=>{ListItemGroup({ header: this.itemHead(item.title) }) {ForEach(item.contacts, (name:string)=> {ListItem() {this.itemContent(name)}})}})}}.title('支持分组列表').titleMode(NavigationTitleMode.Mini)}
}

添加粘性标题

运行效果
在这里插入图片描述
对应代码

List() {...
}
.sticky(StickyStyle.Header)  // 设置吸顶,实现粘性标题效果

控制滚动位置

在这里插入图片描述

对应代码

@Entry
@Component
struct ListScrollToPage {@State listItems:Array<String> = []private listScroller: Scroller = new Scroller();aboutToAppear() {for (var i =0;i< 50;i++) {this.listItems.push(`新闻${i+1}`)}}build() {Navigation() {Stack({ alignContent: Alignment.BottomEnd }) {List({ space: 5, scroller: this.listScroller }) {ForEach(this.listItems, (text: string) => {ListItem() {Text(text).textAlign(TextAlign.Center).width('100%').height(250).backgroundColor('#9dc3e6')}})}Image('image/scroll_to_top.svg').width(50).height(50).margin({right: 10,bottom: 10}).onClick(()=> {this.listScroller.scrollToIndex(0)})}}.title('控制滚动位置').titleMode(NavigationTitleMode.Mini)}
}

响应滚动位置

在这里插入图片描述
对应代码

Stack() {List() {...}.onScrollIndex((start, end)=> {this.firstIndex = start})Text(`当前第一个index:${this.firstIndex}`)...
}

响应列表项侧滑

在这里插入图片描述
对应代码

@Entry
@Component
struct SwipeListPage {@State listItems:Array<String> = []aboutToAppear() {for (var i =0;i< 50;i++) {this.listItems.push(`选项${i+1}`)}}@Builder itemEnd(index: number) {// 侧滑后尾端出现的组件Image("image/delete.svg").width(20).height(20).onClick(() => {this.listItems.splice(index, 1);})}build() {Navigation() {List({space: 5}) {ForEach(this.listItems, (item, index)=> {ListItem() {Text(item).textAlign(TextAlign.Center).width('100%').height(50).backgroundColor('#9dc3e6')}.swipeAction({ end: this.itemEnd.bind(this,index) })})}}.title('左滑删除列表').titleMode(NavigationTitleMode.Mini)}
}

给列表项添加标记

添加标记是一种无干扰性且直观的方法,用于显示通知或将注意力集中到应用内的某个区域。例如,当消息列表接收到新消息时,通常对应的联系人头像的右上方会出现标记,提示有若干条未读消息,如下图所示。
在这里插入图片描述

@Entry
@Component
struct BadgeListPage {@State listItems:Array<String> = []aboutToAppear() {for (var i =0;i< 50;i++) {this.listItems.push(`Item${i+1}`)}}build() {Navigation() {List({space: 5}) {ForEach(this.listItems, (item:string)=> {ListItem() {Row() {// 展示未读数Badge({count: 1,position: BadgePosition.RightTop,style: { badgeSize: 16, badgeColor: '#FA2A2D' }}) {// 未读数的头像Button().width(80).height(80).border({radius:90})}.margin({left:15})// 右侧文字Text(item).fontColor(Color.White).width('100%').height(100).padding({left:20})}}})}.backgroundColor(Color.Gray)}.title('列表项添加标记').titleMode(NavigationTitleMode.Mini)}
}

长列表的处理

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

当使用懒加载方式渲染列表时,为了更好的列表滚动体验,减少列表滑动时出现白块,List组件提供了cachedCount参数用于设置列表项缓存数,只在懒加载LazyForEach中生效。
在这里插入图片描述

@Entry
@Component
struct LazyForEachPage {dataSource:MyDataSource = new MyDataSource();aboutToAppear() {for (var i =0;i< 50;i++) {this.dataSource.pushData(`Item${i+1}`)}}build() {Navigation() {List({space: 5}) {LazyForEach(this.dataSource, (item:string)=> {ListItem() {Text(item).width('100%').height(100).backgroundColor('#9dc3e6')}})}}.title('LazyForEach 列表').titleMode(NavigationTitleMode.Mini)}
}// Basic implementation of IDataSource to handle data listener
class BasicDataSource implements IDataSource {private listeners: DataChangeListener[] = [];getData(index: number) {return ""}totalCount(): number {return 0}// 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听registerDataChangeListener(listener: DataChangeListener): void {if (this.listeners.indexOf(listener) < 0) {console.info('add listener');this.listeners.push(listener);}}// 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听unregisterDataChangeListener(listener: DataChangeListener): void {const pos = this.listeners.indexOf(listener);if (pos >= 0) {console.info('remove listener');this.listeners.splice(pos, 1);}}// 通知LazyForEach组件需要重载所有子组件notifyDataReload(): void {this.listeners.forEach(listener => {listener.onDataReloaded();})}// 通知LazyForEach组件需要在index对应索引处添加子组件notifyDataAdd(index: number): void {this.listeners.forEach(listener => {listener.onDataAdd(index);})}// 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件notifyDataChange(index: number): void {this.listeners.forEach(listener => {listener.onDataChange(index);})}// 通知LazyForEach组件需要在index对应索引处删除该子组件notifyDataDelete(index: number): void {this.listeners.forEach(listener => {listener.onDataDelete(index);})}
}class MyDataSource extends BasicDataSource {private dataArray: string[] = [];totalCount(): number {return this.dataArray.length;}getData(index: number) {return this.dataArray[index];}public addData(index: number, data: string): void {this.dataArray.splice(index, 0, data);this.notifyDataAdd(index);}public pushData(data: string): void {this.dataArray.push(data);this.notifyDataAdd(this.dataArray.length - 1);}
}

上一篇 2.6、媒体查询(mediaquery)
下一篇 2.8、下拉刷新与上拉加载

相关文章:

2.7、创建列表(List)

概述 列表是一种复杂的容器&#xff0c;当列表项达到一定数量&#xff0c;内容超过屏幕大小时&#xff0c;可以自动提供滚动功能。它适合用于呈现同类数据类型或数据类型集&#xff0c;例如图片和文本。在列表中显示数据集合是许多应用程序中的常见要求&#xff08;如通讯录、…...

solr functionquery函数查询自定义函数实现

Solr是一个开源的搜索平台&#xff0c;基于Apache Lucene库构建&#xff0c;主要用于提供全文搜索的功能。它被设计为一个高度可靠、可扩展的搜索应用服务器。以下是Solr的一些主要使用场景&#xff1a; 全文搜索&#xff1a;Solr最核心的功能是提供全文搜索&#xff0c;它可以…...

如何将 Parallels虚拟机 安装或者迁移到 移动硬盘 or U盘?

本文讨论主题 如何安装 Parallels 虚拟机到移动硬盘和U盘? 已经安装到了mac上的虚拟机如何迁移到移动硬盘活着U盘上? 关于Parallels Deskshop 19 虚拟机 安装激活,文末关注公众号AIshape,回复:PD 进行获取通过将虚拟机安装在外置的移动硬盘U盘上,可以节省mac本身SSD的容…...

大型网站集群管理负载均衡

课程介绍 结合企业大规模应用&#xff0c;解决应用高并发问题&#xff0c;解决单节点故障问题&#xff0c;缓存数据库的应用。学完掌握知识点&#xff1a;企业应用实现四七层负载均衡&#xff0c;以及Nginx等应用的高可用性&#xff0c;Redis缓存数据库的部署应用以及高可用方…...

JAVA使用POI实现Excel单元格合并-02

JAVA使用POI实现Excel单元格合并 实现效果 解释&#xff1a;只要是遇见与前一行相同的数据就合并 引入jar <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.2</version></depe…...

深入了解 Linux 中的 MTD 设备:/dev/mtd* 与 /dev/mtdblock*

目录 前言一、什么是MTD子系统&#xff1f;二、 /dev/mtd* 设备文件用途注意事项 三、/dev/mtdblock* 设备文件用途注意事项 三、这两种设备文件的关系四、关norflash的一些小知识 前言 在嵌入式Linux系统的世界里&#xff0c;非易失性存储技术扮演着至关重要的角色。MTD&#…...

2、Spring CLI安装

安装 Spring CLI 提供了多种格式,让您选择自己喜欢的安装方法。可下载的制品可从发布页面获取。 二进制发行版 WindowsLinuxMac手动安装(Windows,其他自己看) spring-cli-standalone-<version>-windows.x86_64.zip - 打包了 x86 JDKspring-cli-installer-<versi…...

数据库备份工具(实现数据定时覆盖)

数据库备份工具&#xff08;实现数据定时覆盖&#xff09; 永远热爱&#xff0c;永远执着&#xff01; 工具介绍 自动化测试数据库更新调度程序 这段 Python 脚本自动化了每天定时从生产数据库更新测试数据库的过程。它利用了 schedule 库来安排并执行每天指定时间的更新任务…...

测试环境搭建整套大数据系统(十二:挂载磁盘到hadoop环境)

一&#xff1a;链接硬盘 将硬盘连接到计算机的 SATA 接口或 USB 接口&#xff0c;并确保硬盘通电并处于可用状态。 二&#xff1a;查看硬盘信息 sudo fdisk -l三&#xff1a;创建分区 gdisk /dev/vbd重新扫描磁盘 partprobe /dev/vdb格式化磁盘 mkfs.ext4 /dev/vdb2查看磁…...

Spring事务核心:声明式事务注解式事务

全解&#xff1a;声明式事务和注解事务 在Spring中&#xff0c;事务管理是一个非常重要的特性&#xff0c;它可以帮助开发者在应用程序中实现事务控制。Spring提供了两种事务管理方式&#xff1a;声明式事务和注解事务。 1. 声明式事务 声明式事务是指通过配置文件或注解的方…...

AcWing 1015. 摘花生

Problem: AcWing 1015. 摘花生 文章目录 思路解题方法复杂度Code 思路 这是一个典型的动态规划问题。我们需要在一个二维网格中&#xff0c;从左上角走到右下角&#xff0c;每次只能向右或向下移动&#xff0c;目标是使得经过的路径上的数字之和最大。 我们可以定义dp[i][j]为从…...

Dalle-3、Sora、Stable Diffusion 3 掀起AIGC新浪潮

随着科技的飞速发展&#xff0c;我们迎来了视觉AIGC高光时刻&#xff0c;一个充满无限可能与机遇的新时代。在这个时代里&#xff0c;三大里程碑Dalle-3、Sora和Stable Diffusion 3以其炸裂式的技术发展&#xff0c;引领着AIGC领域的新浪潮。文章首先做相应简要介绍&#xff0c…...

Unity 视频组件 VideoPlayer

组件添加&#xff1a; 在自己定义的组件下&#xff08;例如&#xff1a;Panel&#xff09; 点击 Inspector 面板中的 AddComponent &#xff0c;输入“VideoPlayer”。 资源 这里 视频资源有两种形式&#xff0c;第一种是 VideoClip &#xff0c;需要将视频文件拖拽到该属性字段…...

RSTP环路避免实验(华为)

思科设备参考&#xff1a;RSTP环路避免实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 RSTP (Rapid Spanning Tree Protocol) 是从STP发展而来 • RSTP标准版本为IEEE802.1w • RSTP具备STP的所有功能&#xff0c;可以兼容STP运行 • RSTP和STP有所不同 减少了…...

Arduino IDE工程代码多文件编程和中文设置

一、esp8266模块信息 二、中英文切换 点击文件( File )–选择首选项( Preference )—选择语言( Language )—选择中文–点击确定( OK ) 三、多文件编程 在Arduino编程中&#xff0c;将代码分割成多个文件是一种很好的做法&#xff0c;特别是项目变得越来越大和复杂时。这样…...

【微服务】Eureka(服务注册,服务发现)

文章目录 1.基本介绍1.学前说明2.当前架构分析1.示意图2.问题分析 3.引出Eureka1.项目架构分析2.上图解读 2.创建单机版的Eureka1.创建 e-commerce-eureka-server-9001 子模块2.检查父子pom.xml1.子 pom.xml2.父 pom.xml 3.pom.xml 引入依赖4.application.yml 配置eureka服务5.…...

windows上ssh设置代理,直接访问公司内网

ssh设置代理一般来说很简单&#xff0c;对于无密码或者可以支持密钥登录的&#xff0c;都比较无脑 难的地方在于使用用户名密码认证来使用一个http的代理或者socks5的代理&#xff0c;密码如何设置&#xff1f;特殊字符如何处理&#xff1f; 直接上答案&#xff0c;.ssh/conf…...

C++ union用法

在C中&#xff0c;union是一种特殊的数据类型&#xff0c;可以在同一个内存位置存储不同的数据类型。它的用法如下&#xff1a; 1. 声明union类型&#xff1a;使用关键字union加上union名称来声明一个union类型。 c union UnionName { dataType1 member1; dataType2 …...

JavaSE_运算符 案例分析

/*符号在字符串中的操作: 表示连接,会将其他内容和字符串连接在一起,形成一个字符串目标:理解符号在字符串中的作用会将其他内容和字符串连接在一起,形成一个字符串*/ public class Operator03 {public static void main(String[] args) {System.out.println("5 5 "…...

15、Spring Cloud Alibaba Sentinel实现熔断与限流

注&#xff1a;本篇文章主要参考周阳老师讲解的cloud进行整理的&#xff01; 1、Sentinel 1.1、官网 https://sentinelguard.io/zh-cn/ 等价对标 Spring Cloud Circuit Breaker 1.2、是什么 https://github.com/alibaba/Sentinel/wiki 1.3、去哪下 https://github.com/alibab…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

ZYNQ学习记录FPGA(一)ZYNQ简介

一、知识准备 1.一些术语,缩写和概念&#xff1a; 1&#xff09;ZYNQ全称&#xff1a;ZYNQ7000 All Pgrammable SoC 2&#xff09;SoC:system on chips(片上系统)&#xff0c;对比集成电路的SoB&#xff08;system on board&#xff09; 3&#xff09;ARM&#xff1a;处理器…...