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.mzph.cn/news/664870.shtml

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

相关文章

React从 EMAScript5编程规范到 EMAScript6编程规范过程中的几点改变

在从ECMAScript 5 (ES5)编程规范转换到ECMAScript 6 (ES6)编程规范的过程中,有几个主要的改变: 块级作用域:ES6引入了let和const关键字,允许在块级作用域中声明变量。在ES5中,变量的作用域仅限于函数内部。 箭头函数&…

a-upload——实现上传功能——基础积累

最近在写后台管理系统&#xff0c;遇到了上传功能&#xff0c;之前写过很多次&#xff0c;再次记录一下&#xff1a; <a-upload:file-list"fileList":remove"handleRemove":before-upload"beforeUpload":customRequest"customRequest&qu…

计算机毕业设计 | SSM 旅游网站后台管理系统(附源码)

1&#xff0c;概述 1.1 背景分析 随着人们生活水平的提高和对休闲旅游的日益重视&#xff0c;旅游业已成为全球最大的经济产业之一。越来越多的人选择通过在线方式进行旅行预订&#xff0c;这种趋势为旅游网站提供了巨大的商机。用户体验是决定旅游网站成功与否的关键因素。良…

Flutter 仿抖音 TikTok 上下滑动 播放视频

Flutter 仿抖音 TikTok 上下滑动 播放视频UI框架&#xff0c;视频播放使用 video_player github&#xff1a;GitHub - PangHaHa12138/TiktokVideo: Flutter 仿抖音 TikTok 上下滑动 播放视频UI框架 实现功能&#xff1a; 1.上下滑动自动播放切换视频&#xff0c;loading 封面…

bash脚本学习笔记

一、扫盲 脚本文件是一种文本文件&#xff0c;其中包含了一系列的命令和指令&#xff0c;可以被操作系统解释器直接解释执行。脚本文件通常被用来完成特定的任务或执行重复性的操作。 脚本文件通常以某种编程语言的语法编写&#xff0c;例如 Bash、Python、Perl、Ruby 等等。…

二叉树的层平均值

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[3.00000,14.50000,11.00000] 解释&#xff1a;第 0 层的平均值为 …

微服务架构风格

1 引言 微服务是一种架构风格&#xff0c;它将应用构建位为一个小型自治服务的集合&#xff0c;以业务领域为模型。通俗地说&#xff0c;就像蜜蜂通过对蜡制的等边六边形单元来构建它们的蜂巢。它们最初从使用材料的小单元开始&#xff0c;一点点的搭建出一个大型蜂巢。这些小单…

【OpenCV学习笔记27】- OpenCV 中的直方图 - 直方图 - 1:查找,绘图,分析

这是对于 OpenCV 官方文档中 图像处理 的学习笔记。学习笔记中会记录官方给出的例子&#xff0c;也会给出自己根据官方的例子完成的更改代码&#xff0c;同样彩蛋的实现也会结合多个知识点一起实现一些小功能&#xff0c;来帮助我们对学会的知识点进行结合应用。 如果有喜欢我笔…

1895_分离进程的能力

1895_分离进程的能力 全部学习汇总&#xff1a; g_unix: UNIX系统学习笔记 (gitee.com) 有些理念可能在控制类的嵌入式系统中不好实施&#xff0c;尤其是没有unix这样的系统搭载的情况下。如果是考虑在RTOS的基础上看是否有一些理念可以做尝试&#xff0c;我觉得还是可以有一定…

快速傅里叶变换 算法与实现

强烈推荐李家同教授 Communications engineering essentials for computer scientists and electrical engineers 一书 该部分关于离散傅里叶变换的讲解是我目前见过最好的 讲得十分清楚&#xff0c;严谨又不过分深入 直觉和物理动机也很明确 对于工程应用完全足够 书籍下载地…

npm 淘宝镜像正式到期,更新使用成功

npm 淘宝镜像原网址&#xff1a;https://registry.npm.taobao.org/ npm 淘宝镜像更新后网址&#xff1a;https://registry.npmmirror.com 过程&#xff1a; 部署 nuxt docker 容器的时候&#xff0c;报以下错&#xff1a; npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CE…

跟着pink老师前端入门教程-day17

2、CSS3 动画 动画&#xff08;animation&#xff09;是CSS3中就要有颠覆性的特征之一&#xff0c;可通过设置多个节点来精确控制一个或一组动画&#xff0c;常用来实现复杂的动画效果 相比较过渡&#xff0c;动画可以实现更多变化&#xff0c;更多控制&#xff0c;连续自动播…

【Simulink系列】——动态系统仿真 之 简单系统

引入 不同的系统具有不同的输入与输出。一般来说&#xff0c;输入输出数目越多&#xff0c;系统越复杂。最简单的系统只要一个输入一个输出&#xff08;SISO&#xff09;&#xff0c;且其任意时刻的输出只与当前时刻的输入有关。 一、简单系统定义 对于满足下列条件的系统&a…

重新配置vue项目时出现的:连接已断开问题

在新机器上配置完node.js、vue-cli&#xff0c;配置了node_modules后&#xff0c;命令行运行vue ui后&#xff0c;出现了如下报错&#xff1a; C:\Users\LEN>vue ui &#x1f680; Starting GUI... &#x1f320; Ready on http://localhost:8000 node:events:496throw e…

揭秘店铺详情API接口:提升顾客信任与购物体验的利器

在电商领域&#xff0c;了解店铺的详细信息对于提升顾客的信任和忠诚度至关重要。为了帮助开发者获取和管理特定店铺的信息&#xff0c;电商平台通常提供店铺详情API接口。本文将指导你如何使用这个API接口来获取店铺的名称、描述、地址、评分等详细信息&#xff0c;并将这些信…

通过 ChatGPT 的 Function Call 查询数据库

用 Function Calling 的方式实现手机流量包智能客服的例子。 def get_sql_completion(messages, model"gpt-3.5-turbo"):response client.chat.completions.create(modelmodel,messagesmessages,temperature0,tools[{ # 摘自 OpenAI 官方示例 https://github.com/…

未定义基类问题解决

基类A, 子类B 原因 出现了超前部署&#xff0c;循环依赖&#xff0c;即A.h中包含了B.h &#xff0c;B.h中包含了A.h从而出现错误。 解决 将基类中的包含头文件#include"B.h"删除即可

想打游戏 可是windows一直出问题 应该如何解决呢 我来告诉你

如何你想让系统一直不出问题 你需要按照我的方法: 1 用 users 用户组用户 不登陆管理员账户 特别不登陆windows默认创建的那个用户 安装软件时 输密码安装 2 不安装国产软件 和 杀毒软件 3 使用firefox这个浏览器 或 google浏览器&#xff08;但gogole不保证安全&…

扩展学习|统计学习理论(SLT)与极限学习机(ELM)应用于大社会数据分析

文献来源&#xff1a;[1] Oneto L , Bisio F , Cambria E ,et al.Statistical Learning Theory and ELM for Big Social Data Analysis[J].IEEE Computational Intelligence Magazine, 2016, 11(3):45-55.DOI:10.1109/MCI.2016.2572540. 提取链接&#xff1a;链接&#xff1a;h…

移远(Quectel)物联网通信解决方案

一、方案简介 无线通信模块是具备无线通信的电路模块&#xff0c;它能通过无线连接传输数据&#xff0c;能识别分析主控制器发来的命令&#xff0c;控制节点设备的工作&#xff0c;或者向主控制器发送当前节点设备的工作状态。 市面上常用的无线通信模组包括蓝牙模组、WLAN模…