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、下拉刷新与上拉加载

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

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

相关文章

LeetCode 面试经典150题 392.判断子序列

题目&#xff1a; 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;例如&#xff0c;"ace"是"abcde"…

基于深度学习的OCR,如何解决图像像素差的问题?

基于深度学习的OCR技术在处理图像像素差的问题时确实面临一定的挑战。图像像素差可能导致OCR系统无法准确识别文本&#xff0c;从而影响其精度和可靠性。尽管已经有一些方法如SRN-Deblur、超分SR和GAN系列被尝试用于解决这个问题&#xff0c;但效果并不理想。然而&#xff0c;这…

安防监控视频汇聚平台EasyCVR在银河麒麟V10系统中的启动异常及解决方法

安防监控视频平台EasyCVR具备较强的兼容性&#xff0c;它可以支持国标GB28181、RTSP/Onvif、RTMP&#xff0c;以及厂家的私有协议与SDK&#xff0c;如&#xff1a;海康ehome、海康sdk、大华sdk、宇视sdk、华为sdk、萤石云sdk、乐橙sdk等。平台兼容性强&#xff0c;支持Windows系…

容器镜像加速指南:探索 Kubernetes 缓存最佳实践

介绍 将容器化应用程序部署到 Kubernetes 集群时&#xff0c;由于从 registry 中提取必要的容器镜像需要时间&#xff0c;因此可能会出现延迟。在应用程序需要横向扩展或处理高速实时数据的情况下&#xff0c;这种延迟尤其容易造成问题。幸运的是&#xff0c;有几种工具和策略…

政安晨:【TensorFlow与Keras实战演绎机器学习】专栏 —— 目录

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎机器学习 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 本篇是作者政安晨的专栏《TensorFlow与Keras…

文献阅读笔记(Transformer)

文献阅读笔记&#xff08;Transformer&#xff09; 摘要Abstract1、文献阅读1.1 文献题目1.2 文献摘要1.3 研究背景1.4 模型架构1.4.1 Encoder-Decoder1.4.2 注意力机制1.4.3 多头注意力1.4.4 Position-wise Feed-Forward Networks1.4.5 Embeddings and Softmax1.4.6 Positiona…

大小端字节序和字节序的判断+有符号整形和无符号整形的取值范围

大小端存在的意义 大小端字节存储方式&#xff08;Big-Endian 和 Little-Endian&#xff09;的存在主要是由于不同计算机体系结构和网络通信标准对数据表示方式的差异所导致的。大小端字节存储方式的存在具有以下意义&#xff1a; 1. 兼容性&#xff1a;不同的计算机系统和网络…

javaWeb网上订餐管理系统

一、简介 在当今社会&#xff0c;随着互联网的普及&#xff0c;网上订餐已经成为了人们生活中不可或缺的一部分。为了方便用户点餐&#xff0c;同时也方便商家管理订单&#xff0c;我设计了一个基于JavaWeb的网上订餐管理系统。该系统分为前台和后台两部分&#xff0c;前台包括…

ChatGPT助力论文写作:详细步骤解析

前言 在论文写作过程中&#xff0c;尽管人工智能工具如ChatGPT能为我们提供有效的辅助&#xff0c;但我们必须铭记&#xff0c;这些工具并不能完全取代我们的思考与判断能力。本指南将详尽地展示如何利用ChatGPT辅助论文写作的全过程&#xff0c;旨在帮助您更高效地完成学术任…

AI基础知识扫盲

AI基础知识扫盲 AIGCLangchain--LangGraph | 新手入门RAG&#xff08;Retrieval-Augmented Generation&#xff09;检索增强生成fastGPT AIGC AIGC是一种新的人工智能技术&#xff0c;它的全称是Artificial Intelligence Generative Content&#xff0c;即人工智能生成内容。 …

uniapp的配置文件、入口文件、主组件、页面管理部分

pages.json 配置文件&#xff0c;全局页面路径配置&#xff0c;应用的状态栏、导航条、标题、窗口背景色设置等 main.js 入口文件&#xff0c;主要作用是初始化vue实例、定义全局组件、使用需要的插件如 vuex&#xff0c;注意uniapp无法使用vue-router&#xff0c;路由须在pag…

[NKCTF 2024]web解析

文章目录 my first cms全世界最简单的CTF解法一解法二 my first cms 打开题目在最下面发现是CMS Made Simple&#xff0c;版本为2.2.19 扫一下发现存在后台登陆界面&#xff0c;直接访问 用字典爆破下admin的密码为Admin123 然后直接登录&#xff0c;去漏洞库搜一下其实存在…

后端常问面经之Java集合

HashMap底层原理 HashMap的数据结构&#xff1a; 底层使用hash表数据结构&#xff0c;即数组和链表或红黑树 当我们往HashMap中put元素时&#xff0c;利用key的hashCode重新hash计算出当前对象的元素在数组中的下标 存储时&#xff0c;如果出现hash值相同的key&#xff0c;此…

恒创科技:服务器反应慢如何解决?

​  通常来说&#xff0c;访问者会在最初的几秒钟内决定是留在您的网站还是离开。如果页面加载时间超过五秒&#xff0c;访问者离开的可能性就会增加 90%。所以&#xff0c;作为站长们&#xff0c;必须减少服务器响应时间&#xff0c;以确保其网站加载速度更快。以下是减少网…

Mac电脑虚拟显示器:BetterDisplay Pro for Mac v2.0.11激活版

BetterDisplay Pro是一款由waydabber开发的Mac平台上的显示器校准软件&#xff0c;可以帮助用户调整显示器的颜色和亮度&#xff0c;以获得更加真实、清晰和舒适的视觉体验。 软件下载&#xff1a;BetterDisplay Pro for Mac v2.0.11激活版 以下是BetterDisplay Pro的主要特点&…

蔚来JAVA面试(收集)

先叠加&#xff0c;这个是自己找的答案不一定对&#xff0c;只是给我参考看看而已。 一、项目 这个没有&#xff0c;根据实际项目情况来。蔚来比较喜欢拷打项目&#xff0c;所以要对项目非常熟悉&#xff08;慌&#xff09; 二、JAVA基础 2.1 Java中的IO模型有用到过吗&#…

Android视角看鸿蒙第九课-鸿蒙的布局

鸿蒙的四大布局 导读 前面八篇文章描述了鸿蒙app的配置文件&#xff0c;关于版本号&#xff0c;开发版本&#xff0c;桌面图标等等配置方式。从这一篇文章开始学习鸿蒙的UI使用方式。 前面我们学习到鸿蒙有ability和page的区分&#xff0c;ability类似Activity但又不完全一样…

如何使用PHP和RabbitMQ实现延迟队列(方式二)?

前言 前几天写了一篇关于PHP和RabbitMQ如何通过插件实现延迟队列的功能。 今天写另外一篇不需要插件的方式&#xff0c;使用RabbitMQ的死信队列&#xff08;Dead-Letter-Exchanges, DLX&#xff09;和消息TTL&#xff08;Time-To-Live&#xff09;。 这种方法涉及到设置消息…

java Web餐馆订单管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 餐馆订单管理系统是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使…

vivo x fold 3Pro参数配置 vivo x fold 3Pro续航

vivo XFold3 Pro采用了顶级的AMOLED折叠屏&#xff0c;屏幕预计会配备一块6.53英寸的外屏以及8.03英寸的内屏&#xff0c;分辨率高达2K级别&#xff0c;屏幕支持120Hz刷新率&#xff0c;色彩鲜艳&#xff0c;视觉效果一流。不论是看电影、玩游戏还是日常使用&#xff0c;都能给…