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

鸿蒙界面开发(九):列表布局 (List)

列表布局

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

布局与约束

列表作为一种容器,会自动按其滚动方向排列子组件,向列表中添加组件或从列表中移除组件会重新排列子组件。
ListItemGroup用于列表数据的分组展示,其子组件也是ListItem。ListItem表示单个列表项,可以包含单个子组件。
说明: List的子组件必须是ListItemGroup或ListItem,ListItem和ListItemGroup必须配合List来使用。

Grid和WaterFlow也可以实现单列、多列布局,如果布局每列等宽,且不需要跨行跨列布局,相比Gird和WaterFlow,则更推荐使用List。

  1. 如果List组件主轴或交叉轴方向设置了尺寸,则其对应方向上的尺寸为设置值。
  2. 如果List组件主轴方向没有设置尺寸,当List子组件主轴方向总尺寸小于List的父组件尺寸时,List 主轴方向尺寸自动适应子组件的总尺寸。如果List的子组件主轴方向总尺寸超过List的父组件尺寸时,List主轴方向尺寸适应List的父组件尺寸。
  3. List组件交叉轴方向在没有设置尺寸时,其尺寸默认自适应父组件尺寸

开发布局

设置主轴方向

List() { // ...}
.listDirection(Axis.Horizontal)
listDirection属性设置为Axis.Horizontal,水平滚动。
listDirection默认为Axis.Vertical,即主轴默认是垂直方向。

设置交叉轴布局

List组件的交叉轴布局可以通过lanes和alignListItem属性进行设置,
lanes属性用于确定交叉轴排列的列表项数量,
alignListItem用于设置子组件在交叉轴方向的对齐方式。

lanes

List组件的lanes属性通常用于在不同尺寸的设备自适应构建不同行数或列数的列表,即一次开发、多端部署的场景,例如歌单列表。
lanes属性的取值类型是"number | LengthConstrain",即整数或者LengthConstrain类型。
当其取值为LengthConstrain类型时,表示会根据LengthConstrain与List组件的尺寸自适应决定行或列数。

//取值为number
List() { // ...}
.lanes(2)
//取值为LengthConstrain类型
@Entry
@Component
struct EgLanes {@State egLanes: LengthConstrain = { minLength: 200, maxLength: 300 }build() {List() { // ...}.lanes(this.egLanes)}
}
当List组件宽度为300vp时,由于minLength为200vp,此时列表为一列。
当List组件宽度变化至400vp时,符合两倍的minLength,则此时列表自适应为两列。

alignListItem属性

默认值是ListItemAlign.Start,即列表项在列表交叉轴方向上默认按首部对齐。
ListItemAlign.Center表示列表项在水平方向上居中对齐。

List() { // ...}
.alignListItem(ListItemAlign.Center)

在列表中显示数据

ListItem中只能有一个根节点组件,若列表项是由多个组件元素组成的,则需要将这多个元素组合到一个容器组件内或组成一个自定义组件。

List() {ListItem() {Row() {Image($r('app.media.iconE')).width(40).height(40).margin(10)Text('小明').fontSize(20)}}}

迭代列表内容

通常,应用通过数据集合动态地创建列表。使用循环渲染可从数据源中迭代获取数据,并在每次迭代过程中创建相应的组件,降低代码复杂度。

ArkTS通过ForEach提供了组件的循环渲染能力。

import { util } from '@kit.ArkTS'class Contact {key: string = util.generateRandomUUID(true);name: string;icon: Resource;constructor(name: string, icon: Resource) {this.name = name;this.icon = icon;}
}@Entry
@Component
struct SimpleContacts {private contacts: Array<object> = [new Contact('小明', $r("app.media.iconA")),new Contact('小红', $r("app.media.iconB")),]build() {List() {ForEach(this.contacts, (item: Contact) => {ListItem() {Row() {Image(item.icon).width(40).height(40).margin(10)Text(item.name).fontSize(20)}.width('100%').justifyContent(FlexAlign.Start)}}, (item: Contact) => JSON.stringify(item))}.width('100%')}
}

自定义列表样式

设置内容间距——space参数

List({ space: 10 }) {// ...
}

添加分隔线——divider属性

divider属性用于给列表项之间添加分隔线。在设置divider属性时,可以通过strokeWidth和color属性设置分隔线的粗细和颜色。
startMargin和endMargin属性分别用于设置分隔线距离列表侧边起始端的距离和距离列表侧边结束端的距离。

class DividerTmp {strokeWidth: Length = 1startMargin: Length = 60endMargin: Length = 10color: ResourceColor = '#ffe9f0f0'constructor(strokeWidth: Length, startMargin: Length, endMargin: Length, color: ResourceColor) {this.strokeWidth = strokeWidththis.startMargin = startMarginthis.endMargin = endMarginthis.color = color}
}
@Entry
@Component
struct EgDivider {@State egDivider: DividerTmp = new DividerTmp(1, 60, 10, '#ffe9f0f0')build() {List() {// ... }.divider(this.egDivider)}
}

说明

分隔线的宽度会使ListItem之间存在一定间隔,当List设置的内容间距小于分隔线宽度时,ListItem之间的间隔会使用分隔线的宽度。当List存在多列时,分割线的startMargin和endMargin作用于每一列上。List组件的分隔线画在两个ListItem之间,第一个ListItem上方和最后一个ListItem下方不会绘制分隔线。

添加滚动条——scrollBar属性

在使用List组件时,可通过scrollBar属性控制列表滚动条的显示。scrollBar的取值类型为BarState,当取值为BarState.Auto表示按需显示滚动条。此时,当触摸到滚动条区域时显示控件,可上下拖拽滚动条快速浏览内容,拖拽时会变粗。若不进行任何操作,2秒后滚动条自动消失。

scrollBar属性API version 9及以下版本默认值为BarState.Off,从API version 10版本开始默认值为BarState.Auto。

List() { // ...}
.scrollBar(BarState.Auto)

支持分组列表——ListItemGroup

在List组件中使用ListItemGroup对项目进行分组,可以构建二维列表。
ListItemGroup的宽度默认充满List组件。在初始化ListItemGroup时,可通过header参数设置列表分组的头部组件。

@Entry
@Component
struct ContactsList {@Builder itemHead(text: string) {// 列表分组的头部组件,对应联系人分组A、B等位置的组件Text(text).fontSize(20).backgroundColor('#fff1f3f5').width('100%').padding(5)}build() {List() {ListItemGroup({ header: this.itemHead('A') }) {// 循环渲染分组A的ListItem}}}
}

添加粘性标题——sticky属性

粘性标题是一种常见的标题模式,常用于定位字母列表的头部元素。如在联系人列表中滚动A部分时,B部分开始的头部元素始终处于A的下方。而在开始滚动B部分时,B的头部会固定在屏幕顶部,直到所有B的项均完成滚动后,才被后面的头部替代。

List组件的sticky属性配合ListItemGroup组件使用,用于设置ListItemGroup中的头部组件是否呈现吸顶效果或者尾部组件是否呈现吸底效果。

设置sticky属性为StickyStyle.Header,即可实现列表的粘性标题效果。
如果需要支持吸底效果,可以通过footer参数初始化ListItemGroup的底部组件,并将sticky属性设置为StickyStyle.Footer。ListItemGroup({ header: this.itemHead(itemGroup.title) }) {// 循环渲染ListItem
}.sticky(StickyStyle.Header)  // 设置吸顶,实现粘性标题效果

控制滚动位置

用户滚动列表到一定位置时,希望快速滚动到列表底部或返回列表顶部。此时,可以通过控制滚动位置来实现列表的快速定位。
List组件初始化时,可以通过scroller参数绑定一个Scroller对象,就可以通过Scroller对象的scrollToIndex方法使列表滚动到指定的列表项索引位置。

首先,需要创建一个Scroller的对象listScroller。

private listScroller: Scroller = new Scroller();

然后,通过将listScroller用于初始化List组件的scroller参数,完成listScroller与列表的绑定。在需要跳转的位置指定scrollToIndex的参数为0,表示返回列表顶部。

Stack({ alignContent: Alignment.Bottom }) {// 将listScroller用于初始化List组件的scroller参数,完成listScroller与列表的绑定。List({ space: 20, scroller: this.listScroller }) {// ...}Button() {// ...}.onClick(() => {// 点击按钮时,指定跳转位置,返回列表顶部this.listScroller.scrollToIndex(0)})
}

响应滚动位置

监听列表的滚动位置变化并作出响应
在这里插入图片描述

当联系人列表从A滚动到B时,右侧索引栏也需要同步从选中A状态变成选中B状态。此场景可以通过监听List组件的onScrollIndex事件来实现,右侧索引栏需要使用字母表索引组件AlphabetIndexer

在列表滚动时,根据列表此时所在的索引值位置firstIndex,重新计算字母索引栏对应字母的位置selectedIndex。由于AlphabetIndexer组件通过selected属性设置了选中项索引值,当selectedIndex变化时会触发AlphabetIndexer组件重新渲染,从而显示为选中对应字母的状态。

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'];
@Entry
@Component
struct ContactsList {@State selectedIndex: number = 0;private listScroller: 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)}}
}

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

响应列表项侧滑——swipeAction属性

给列表项添加标记——Badge组件

下拉刷新与上拉加载

编辑列表

新增列表项

删除列表项

长列表的处理——懒加载

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

相关文章:

鸿蒙界面开发(九):列表布局 (List)

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

微服务远程调用(nacos及OpenFeign简单使用)

问题&#xff1a;在微服务中&#xff0c;每个项目是隔离开的&#xff0c;当有一个项目请求其他项目中的数据时&#xff0c;必须发起网络请求&#xff0c;本文即对此问题展开讨论。 1.使用restTemplate发送请求 //发送请求ResponseEntity<List<ItemDTO>> response …...

Protobuf vs Thrift: 高性能序列化框架的对比与分析

Protobuf&#xff08;Protocol Buffers&#xff09;和Thrift都是高性能、跨语言的序列化框架&#xff0c;它们在数据通信和服务开发中扮演着重要角色。下面从多个方面对它们进行详细对比&#xff1a; 一、概述 1. Protobuf 简介&#xff1a;Protobuf是Google开发的一种语言中…...

LeetCode Hot100 C++ 哈希 1.两数之和

LeetCode Hot100 C 1.两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。 你可以按…...

Windows下安装Neo4j流程

Neo4j简介 Neo4j 是一个基于图形结构的 NoSQL 数据库&#xff0c;专门用于存储和管理图数据。与传统的关系型数据库不同&#xff0c;Neo4j 使用 图&#xff08;graph&#xff09;的形式来表示数据&#xff0c;其中数据点&#xff08;称为 节点&#xff09;通过 边&#xff08;…...

Spring IDEA 2024 自动生成get和set以及toString方法

1.简介 在IDEA中使用自带功能可以自动生成get和set以及toString方法 2.步骤 在目标类中右键&#xff0c;选择生成 选择Getter和Setter就可以生成每个属性对应的set和get方法&#xff0c; 选择toString就可以生成类的toString方法&#xff0c;...

部署my2sql

binlog解析及闪回工具 MySQL闪回工具简介 及 binlog2sql工具用法 安装&#xff1a; unzip my2sql-master.zip cd my2sql-master go build . 使用要求&#xff1a; 1、使用回滚/闪回功能时&#xff0c;binlog格式必须为row,且binlog_row_imagefull&#xff0c; DML统计以及大…...

Android Studio 真机USB调试运行频繁掉线问题

一、遇到问题 Android Studio使用手机运行项目时&#xff0c;总是频繁掉线&#xff0c;连接很不稳定&#xff0c;动不动就消失&#xff0c;基本上无法使用 二、问题出现原因 1、硬件问题&#xff1a;数据线 换条数据线试试&#xff0c;如果可以&#xff0c;那就是数据线的…...

如何通过费曼技巧理解复杂主题

在软件工程领域&#xff0c;知道某件事的名称和真正理解其工作原理之间存在巨大差异。 你可能知道某台机器或某个软件的名称&#xff0c;但你是否真的理解它是如何运作和完成任务的&#xff1f; 在如此复杂且不断发展的领域中&#xff0c;这种区别至关重要。 通过“教学反馈…...

Golang优雅关闭gRPC实践

本文主要讨论了在 Go 语言中实现gRPC服务优雅关闭的技术和方法&#xff0c;从而确保所有连接都得到正确处理&#xff0c;防止数据丢失或损坏。原文: Go Concurrency — Graceful Shutdown 问题 我在上次做技术支持的时候&#xff0c;遇到了一个有趣的错误。我们的服务在 Kubern…...

Maven笔记(一):基础使用【记录】

Maven笔记&#xff08;一&#xff09;-基础使用 Maven是专门用于管理和构建Java项目的工具&#xff0c;它的主要功能有&#xff1a; 提供了一套标准化的项目结构 Maven提供了一套标准化的项目结构&#xff0c;所有IDE(eclipse、myeclipse、IntelliJ IDEA 等 项目开发工具) 使…...

[vulnhub] Jarbas-Jenkins

靶机链接 https://www.vulnhub.com/entry/jarbas-1,232/ 主机发现端口扫描 扫描网段存活主机&#xff0c;因为主机是我最后添加的&#xff0c;所以靶机地址是135的 nmap -sP 192.168.75.0/24 // Starting Nmap 7.93 ( https://nmap.org ) at 2024-09-21 14:03 CST Nmap scan…...

js设计模式(26)

js设计模式(26) JavaScript 中常用的设计模式可以分为几大类&#xff0c;包括创建型模式、结构型模式和行为型模式。以下是它们的分类和常见设计模式的完整列表&#xff1a; 一、创建型模式 这些模式主要关注对象的创建方式&#xff0c;目的是降低系统耦合和复杂性。 工厂模…...

数据库中, drop、delete与truncate的区别?

在数据库中&#xff0c;drop、delete和truncate都可以用于删除数据&#xff0c;但它们之间有以下区别&#xff1a; 一、作用对象 drop&#xff1a;可以删除数据库对象&#xff0c;如表、视图、索引、存储过程等。例如&#xff1a;DROP TABLE table_name;可以删除名为 table_na…...

2024年项目经理不能错过的开源项目管理系统大盘点:全面指南

在2024年&#xff0c;随着项目管理领域的不断发展&#xff0c;开源项目管理系统成为了项目经理们提升工作效率的利器。本文将全面盘点几款备受推荐的开源项目管理系统&#xff0c;帮助项目经理们找到最佳选择&#xff0c;不容错过。 在项目管理日益复杂的今天&#xff0c;开源项…...

MATLAB基本语句

MATLAB语言为解释型程序设计语言。在程序中可以出现顺序、选择、循环三种基本控制结构&#xff0c;也可以出现对M-文件的调用(相当于对外部过程的调用)。 由于 MATLAB开始是用FORTRAN语言编写、后来用 C语言重写的&#xff0c;故其既有FORTRAN的特征&#xff0c;又在许多语言规…...

委托的注册及注销+观察者模式

事件 委托变量如果公开出去&#xff0c;很不安全&#xff0c;外部可以随意调用 所以取消public,封闭它&#xff0c;我们可以自己书写两个方法&#xff0c;供外部注册与注销&#xff0c;委托调用在子方法里调用&#xff0c;这样封装委托变量可以使它更安全&#xff0c;这个就叫…...

Jetpack02-LiveData 数据驱动UI更新(类似EventBus)

前提 LiveData使用了Lifecycle的生命周期&#xff0c;阅读本文前&#xff0c;请先了解Lifecycle源码。 简介 LiveData本质是数据类型&#xff0c;当改变数据的时候&#xff0c;会通知观察者&#xff0c;且只在界面可见的时候才会通知观察者。只能在主线程注册观察者&#xf…...

Redis 的 Java 客户端有哪些?官方推荐哪个?

Redis 官网展示的 Java 客户端如下图所示&#xff0c;其中官方推荐的是标星的3个&#xff1a;Jedis、Redisson 和 lettuce。 Redis 的 Java 客户端中&#xff0c;Jedis、Lettuce 和 Redisson 是最常用的三种。以下是它们的详细比较&#xff1a; Jedis&#xff1a; 线程安全&…...

工作笔记20240927——vscode + jlink调试

launch.json的配置&#xff0c;可以用的 {"name": "Debug","type": "cppdbg","request": "launch","miDebuggerPath": "./arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-g…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...