Compose | UI组件(十二) | Lazy Layout - 列表

文章目录

  • 前言
    • LazyListScope作用域 用来干什么?
    • LazyColumn组件含义?
    • LazyColumn的基本使用
      • LazyColumn Padding设置边距
      • LazyColumn 设置边距 (contentPadding)
      • LazyColumn 为每个子项设置边距 (Arrangement.spacedBy())
      • LazyColumn 根据 rememberLazyListState 记录item位置
      • 根据 items函数 新增 一个key参数,增加和删除操作时,提高页面性能问题
    • LazyRow的含义
      • LazyRow的使用
  • 总结


前言

现在应用市场上很多产品都少不了列表展示需求场景,例如通讯录,短信,音乐列表等等。

所以本篇文章讲解的组件 - 列表LazyListLazyRow


在了解 LazyListLazyRow 之前,我们先了解下 LazyListScope作用域

LazyListScope作用域 用来干什么?

LazyColumnLazyRow 内部都是继承 LazyList组件 实现,但 LazyList 不能直接使用

LazyListcontent 是一个 LazyListScope.() -> Unit 类型的作用域
LazyListScope 提供了 item , items(Int) , item(List) , itemsIndexed(List) 扩展函数来展示列表内容

item:展示单项数据
items(Int):展示多项整型数据
items(List) 展示一组集合数据
itemsIndexed(List) 展示一组集合数据,并且带有下标

val list = ('A'..'Z').map { it.toString() }
LazyColumn{item { Text(text = "first item") }items(10){ index ->Text(text = "$index")}item { Text(text = "last item") }items(list){  item ->Text(text = item)}itemsIndexed(list){ index, item ->Text(text = "$index/$item")}
}

LazyColumn组件含义?

LazyColumn 就是一个纵向滚动列表,用来显示一组纵向数据,并且可以滑动列表

@Composable
fun LazyColumn(modifier: Modifier = Modifier,                                     //修饰符state: LazyListState = rememberLazyListState(),                    //记录列表位置状态contentPadding: PaddingValues = PaddingValues(0.dp),               //整体内容周围的一个边距reverseLayout: Boolean = false,                                    //是否反转列表verticalArrangement: Arrangement.Vertical =if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,   //子组件纵向对齐方式horizontalAlignment: Alignment.Horizontal = Alignment.Start,       //子组件横向对齐方式flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), //fling行为处理逻辑userScrollEnabled: Boolean = true,                                 //是否允许滑动content: LazyListScope.() -> Unit                                  //LazyList作用域
)

LazyColumn的基本使用

LazyColumn 组件 相比传统的 RecyclerView 少写很多代码
RecyclerView 需要在xml中声明一个RecyclerView控件,再在xml中声明一个子控件,再创建一个适配器Adapter,最后在activity中 指定 RecyclerView 的布局类型,再为其填充数据
LazyColumn 就很简单了,看如下代码的实现,就知道了

@Composable
fun LazyColumnList() {LazyColumn {items(20) { i ->Text(text = "Item $i",modifier = Modifier.fillMaxWidth().height(60.dp))}}
}

LazyColumn Padding设置边距

Padding可以设置列表边距,但是会出现切割现象,我们来看下代码

    val list = ('A'..'Z').map { it.toString() }LazyColumn {itemsIndexed(list) { index, letter ->Card(modifier = Modifier.width(120.dp).height(200.dp).padding(10.dp)) {Text(text = "$index $letter",textAlign = TextAlign.Center,fontSize = 20.sp,modifier = Modifier.fillMaxSize().wrapContentHeight(Alignment.CenterVertically))}}}

现在看下运行代码的效果:
在这里插入图片描述

注:
从上图可以看出来最后一个出现了被切割现象,那如何解决这个问题呢?

那就要用到 LazyColumn 提供的 contentPadding 解决

LazyColumn 设置边距 (contentPadding)

LazyColumn 设置边距用的是contentPadding,能保证上下两边的边距相等同时,还不会在滚动的时候,出现切割现象

val list = ('A'..'Z').map { it.toString() }
LazyColumn(contentPadding = PaddingValues(top = 40.dp, start = 10.dp, bottom = 40.dp, end = 10.dp)) {itemsIndexed(list) { index, letter ->Card(modifier = Modifier.fillMaxWidth().height(120.dp)
//                    .padding(10.dp)) {Text(text = "$index $letter",textAlign = TextAlign.Center,fontSize = 20.sp,modifier = Modifier.fillMaxSize().wrapContentHeight(Alignment.CenterVertically))}}}

现在再看下效果图:
在这里插入图片描述

注:
现在可以看出来,没有切割的现象了,但有个问题,中间没有了间距
Lazy Layout提供了专门给子项之间设置边距的属性,使用Arrangement.spacedBy()即可

LazyColumn 为每个子项设置边距 (Arrangement.spacedBy())

Arrangement.spacedBy() 专门为子项设置边距

val list = ('A'..'Z').map { it.toString() }
LazyColumn(contentPadding = PaddingValues(top = 40.dp, start = 10.dp, bottom = 40.dp, end = 10.dp),verticalArrangement = Arrangement.spacedBy(20.dp)) {itemsIndexed(list) { index, letter ->Card(modifier = Modifier.fillMaxWidth().height(120.dp)) {Text(text = "$index $letter",textAlign = TextAlign.Center,fontSize = 20.sp,modifier = Modifier.fillMaxSize().wrapContentHeight(Alignment.CenterVertically))}}
}

效果图如下:
在这里插入图片描述

LazyColumn 根据 rememberLazyListState 记录item位置

有时候有这样的需求:让组件随着列表的滚动进行一些额外的响应。如随着滚动隐藏和显示某个组件
这时候 rememberLazyListState 就排上用场了

以下是rememberLazyListState 源码:

@Composable
fun rememberLazyListState(initialFirstVisibleItemIndex: Int = 0,        //第一个可见子项元素的下标initialFirstVisibleItemScrollOffset: Int = 0  //第一个可见子项元素的偏移距离
): LazyListState {return rememberSaveable(saver = LazyListState.Saver) {LazyListState(initialFirstVisibleItemIndex,initialFirstVisibleItemScrollOffset)}
}

根据列表第一项可见显示组件,不可见隐藏组件

@SuppressLint("FrequentlyChangedStateReadInComposition")
@Composable
fun ListLayout() {val state = rememberLazyListState()Box {val list = ('A'..'Z').map { it.toString() }LazyColumn(state = state,contentPadding = PaddingValues(top = 40.dp, start = 10.dp, bottom = 40.dp, end = 10.dp),verticalArrangement = Arrangement.spacedBy(20.dp)) {itemsIndexed(list) { index, letter ->Card(modifier = Modifier.fillMaxWidth().height(120.dp)) {Text(text = "$index $letter",textAlign = TextAlign.Center,fontSize = 20.sp,modifier = Modifier.fillMaxSize().wrapContentHeight(Alignment.CenterVertically))}}}if (state.firstVisibleItemIndex  == 0) {FloatingActionButton(onClick = {},shape = CircleShape,modifier = Modifier.align(Alignment.CenterEnd).padding(20.dp)) {Icon(Icons.Filled.Star, "Add Button")}}}
}

在这里插入图片描述

根据 items函数 新增 一个key参数,增加和删除操作时,提高页面性能问题

因为compose中往列表添加一项数据,就会整体往后移,数据越多,页面性能越差
所以Google给出了一个解决方案:在items函数添加一个唯一标识的key

@Composable
fun SubVerticalScrollable() {val list = ('A'..'Z').map { it.toString() }LazyColumn(modifier = Modifier.height(300.dp)) {items(list, key = { it }) { letter ->...}}
}

LazyRow的含义

LazyRow 和 LazyColumn用法基本相同,唯一不同的是横向布局的列表组件

@Composable
fun LazyRow(modifier: Modifier = Modifier,                                     //修饰符state: LazyListState = rememberLazyListState(),                    //记录列表位置状态contentPadding: PaddingValues = PaddingValues(0.dp),               //整体内容周围的一个边距reverseLayout: Boolean = false,                                    //是否反转列表horizontalArrangement: Arrangement.Horizontal =if (!reverseLayout) Arrangement.Start else Arrangement.End,    //子组件横向对齐方式verticalAlignment: Alignment.Vertical = Alignment.Top,             //子组件纵向对齐方式flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), //fling行为处理逻辑userScrollEnabled: Boolean = true,                                 //是否允许滑动content: LazyListScope.() -> Unit                                  //LazyList作用域
)

LazyRow的使用

val list = ('A'..'Z').map { it.toString() }
LazyRow(state = state,contentPadding = PaddingValues(top = 40.dp, start = 10.dp, bottom = 40.dp, end = 10.dp),horizontalArrangement = Arrangement.spacedBy(20.dp)) {itemsIndexed(list) { index, letter ->Card(modifier = Modifier.height(300.dp).width(120.dp)) {Text(text = "$index $letter",textAlign = TextAlign.Center,fontSize = 20.sp,modifier = Modifier.fillMaxSize().wrapContentHeight(Alignment.CenterVertically))}}
}

到这里,基本上Lazy Layout 基本上覆盖到了,还有什么问题,欢迎反馈和评论区留言


总结

  1. LazyListScope作用域提供了 item , items(Int) , item(List) , itemsIndexed(List) 扩展函数来展示列表内容
  2. LazyColumn 就是一个纵向滚动列表
  3. contentPadding 设置列表组件的整个内容的边距
  4. Arrangement.spacedBy() 为列表的每个子项设置边距
  5. LazyColumn 根据 rememberLazyListState 记录第一个可见子项元素位置
  6. items函数 新增 一个key参数,设置唯一性,增加和删除操作时,性能得到优化和提高
  7. LazyRow 是一个横向布局的列表组件,用法和 LazyColumn一致

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

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

相关文章

如何在centos云服务器上持续运行

一、直接上命令 cd到jar包所在目录 输入命令运行 nohup java -jar xxx.jar & 退出当前命令 二、云服务器上安装宝塔管理面板 直接用宝塔的进程守护,设置好当前进程输入参数保存就ok

大规模机器学习简介

1. 非线性回归问题 1.1 问题描述 我们有一组实验数据,每个实验都给出了输入和输出对 (Xn, Yn)。每个输入 是空间中的一个点,每个输出 是 空间中的一个点。这些数据点被假设为独立同分布(i.i.d)。 我们的目标是找到一个函数 fw&…

智慧商城(continue)

文章目录 1.静态页面结构准备和动态渲染2.搜索 - 历史记录管理1. 写好基础静态页面,可以先往里面加一点假数据2. 上面基本的渲染直接利用history渲染就可以了3. 搜索历史基本渲染结束了,开始点击搜索添加历史4. vant内用v-model" ",可以快速拿到搜索框的值5. 往历史记…

2024年美国大学生数学建模比赛MCM问题B:搜索潜水器-思路解析与代码解答

2024 MCM Problem B Searching for Submersibles 一、题目翻译 背景: 总部位于希腊的小型海上巡航潜艇(MCMS)公司,制造能够将人类运送到海洋最深处的潜水器。潜水器被移动到该位置,并不受主船的束缚。MCMS现在希望用…

IP地址查询网络威胁:解析威胁、防范攻击

随着互联网的不断普及和发展,网络威胁也愈发严峻。对IP地址进行查询以解析网络威胁,成为网络安全领域一项重要的工作。本文将深入探讨IP地址查询网络威胁的原理、应用场景、防范策略以及未来的发展方向。 IP地址查询网络威胁原理 IP地址查询IP数据云 -…

【Java程序设计】【C00243】基于Springboot的社区医院管理系统(有论文)

基于Springboot的社区医院管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的社区医院管理服务系统 本系统分为系统功能模块、管理员功能模块、用户功能模块以及医生功能模块。 系统功能模块:社…

泰克示波器(TBS2000系列)触发功能使用讲解——边沿触发

# Trigger区域 触发区域用于对触发功能进行配置。示波器的触发功能用于采集(Acquire)那些在瞬间出现的信号,便于我们分析观察,此时可以当做逻辑分析仪使用。触发区域按钮包括:menu、Level\Force Trig三个。 目录 1.1 …

java设计模式:策略模式

在平常的开发工作中,经常会用到不同的设计模式,合理的使用设计模式,可以提高开发效率,提高代码质量,提高代码的可拓展性和维护性。今天来聊聊策略模式。 策略模式是一种行为型设计模式,运行时可以根据需求动…

STM32 UART/USART与RTOS的多任务通信和同步机制设计

在STM32微控制器中,UART/USART与RTOS的多任务通信和同步机制设计可以通过操作系统提供的任务调度机制和各种同步原语(例如信号量、邮箱、消息队列等)来实现。在下面的解释中,我将介绍如何设计基于FreeRTOS的STM32多任务通信和同步…

ZigBee学习——在官方例程基础实现点灯

IAR版本 :10.10.1 Z-stack版本 :3.0.2 文章目录 一、买的板子原理图二、实现过程2.1 重定义LED的物理映射(HAL层)2.2 创建LED事件(应用层)2.2.1 定义用户事件2.2.2 修改zclGenericApp_event_loop() 2.3 触发事件 一、买的板子原理图 二、实现过程 2.1 重定义LED的物理映射(HAL…

分库分表 21 条法则,hold 住!

大家好~今天给大家分享分库分表的 21 条法则 我们结合具体业务场景,以t_order表为例进行架构优化。由于数据量已经达到亿级别,查询性能严重下降,因此我们采用了分库分表技术来处理这个问题。具体而言,我们将原本的单库…

数据结构中的时间复杂度和空间复杂度基础

目录 数据结构 数据结构中的基本名词 数据 数据对象 数据元素 数据项 数据类型 数据对象、数据元素和数据项之间的关系 数据结构及分类 逻辑结构 物理结构 算法 算法的特点 算法设计上的要求 算法效率的衡量 时间复杂度 大O渐进表示法 最坏情况和平均情况 常…