当前位置: 首页 > 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…...

Python | Leetcode Python题解之第433题最小基因变化

题目&#xff1a; 题解&#xff1a; class Solution:def minMutation(self, start: str, end: str, bank: List[str]) -> int:if start end:return 0def diffOne(s: str, t: str) -> bool:return sum(x ! y for x, y in zip(s, t)) 1m len(bank)adj [[] for _ in ra…...

opengauss使用遇到的问题,随时更新

一、查看数据库状态的方式 1、gs_ctl -D /opt/huawei/install/data/dn/ status 2、gs_om -t status --detail 3、cm_ctl query -Cv二、opengauss打印WDR性能报告 1、开启WDR性能参数开关 gs_guc reload -N all -D /opt/huawei/install/data/dn -c "enable_wdr_snap…...

从环境部署到开发实战:消息队列 RocketMQ

文章目录 一、消息队列简介1.1 什么是消息队列1.2 常见消息队列对比1.3 RockectMQ 核心概念1.4 RockectMQ 工作机制 &#xff08;★&#xff09; 二、RocketMQ 部署相关2.1 服务器单机部署2.2 管控台页面 三、RocketMQ 的基本使用3.1 入门案例3.2 消息发送方式3.2.1 同步消息3.…...

【机器学习(九)】分类和回归任务-多层感知机(Multilayer Perceptron,MLP)算法-Sentosa_DSML社区版

文章目录 一、算法概念二、算法原理&#xff08;一&#xff09;感知机&#xff08;二&#xff09;多层感知机1、隐藏层2、激活函数sigma函数tanh函数ReLU函数 3、反向传播算法 三、算法优缺点&#xff08;一&#xff09;优点&#xff08;二&#xff09;缺点 四、MLP分类任务实现…...

渗透测试-文件上传绕过思路

文件上传绕过思路 引言 分享一些文件上传绕过的思路&#xff0c;下文内容多包含实战图片&#xff0c;所以打码会非常严重&#xff0c;可多看文字表达&#xff1b;本文仅用于交流学习&#xff0c; 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#x…...

等保测评中的密码学应用分析

等保测评中密码学应用的分析 等保测评&#xff08;信息安全等级保护测评&#xff09;是中国信息安全领域的一项重要活动&#xff0c;旨在评估信息系统的安全性&#xff0c;并根据评估结果给予相应的安全等级。在等保测评中&#xff0c;密码学应用分析是评估信息系统安全性的关键…...

LCR 007. 三数之和

文章目录 1.题目2.思路3.代码 1.题目 LCR 007. 三数之和 给定一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a &#xff0c;b &#xff0c;c *&#xff0c;*使得 a b c 0 &#xff1f;请找出所有和为 0 且 不重复 的三元组。 示例 1&#xff1a…...

【入门01】arcgis api 4.x 创建地图、添加图层、添加指北针、比例尺、图例、卷帘、图层控制、家控件(附完整源码)

1.效果 2.代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title></title><link rel"s…...

STL迭代器标签

STL&#xff08;标准模板库&#xff09;迭代器标签是用来标识迭代器类型的分类机制。这些标签有助于确定迭代器的特性&#xff0c;比如它是否可以进行随机访问、是否支持修改元素等。主要的迭代器标签包括&#xff1a; Input Iterator&#xff1a;只读迭代器&#xff0c;可以顺…...

容器学习之SparseArray源码解析

1、SparseArray是android sdk 提供集合类&#xff0c;主要用来替换key 为int类型&#xff0c;value为Object类型的Hashmap 2、SparseArray和HashMap相比优缺点&#xff1a; 优点&#xff1a; 1、SparseArray存在一个int[]keys, 因此避免自动装箱 2、SparseArray扩容时只需要数…...