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

news2024/9/27 23:24:59

文章目录

  • 前言
    • 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.coloradmin.cn/o/1429579.html

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

相关文章

C++文件操作(2)

文件操作(2) 1.二进制模式读取文本文件2.使用二进制读写其他类型内容3.fstream类4.文件的随机存取文件指针的获取文件指针的移动 1.二进制模式读取文本文件 用二进制方式打开文本存储的文件时,也可以读取其中的内容,因为文本文件…

通过WSL2来实现Windows10/11的深度学习模型GPU加速,TensorFlow项,Jupyter及其插件安装,CQF心得,金融量化

通过WSL2来实现TF的GPU加速 为什么要用WSL(Windows Subsystem Linux)安装WSL2,miniconda,cuda,cudnn,TA-Lib安装 WSL2安装 Miniconda3安装 CUDA安装 cuDNN安装 TensorFlow 库安装 TA-Lib 库安装其它CQF及金…

MySQL-----DML基础操作

DML语句 DML英文全称是Data Manipulation Language(数据操作语言),用来对数据库中表的数据记录进行增删改操作。 ▶ 添加数据(INSERT) 【语法】 1. 给指定字段添加数据 INSERTO 表名 (字段名1,字段名2,...) VALUES (值1,值2,...); 2.给全…

获取真实 IP 地址(二):绕过 CDN(附链接)

一、DNS历史解析记录 DNS 历史解析记录指的是一个域名在过去的某个时间点上的DNS解析信息记录。这些记录包含了该域名过去使用的IP地址、MX记录(邮件服务器)、CNAME记录(别名记录)等 DNS 信息。DNS 历史记录对于网络管理员、安全研…

跟着cherno手搓游戏引擎【19】抽象纹理

引入: 导入stb_image: GitHub - nothings/stb: stb single-file public domain libraries for C/C 下载复制stb_image.h的内容(8000多行),然后粘到如图位置 stb_image.cpp: #include"ytpch.h" #define STB_IMAGE_IM…

LabVIEW叶片厚度远程监控

LabVIEW叶片厚度远程监控 随着网络技术的高速发展,远程监控广泛应用在各个领域。本文介绍了一种基于LabVIEW的植物叶片厚度远程监控系统,旨在实现对植物生长状况的精准监测和分析。 该系统利用LabVIEW软件开发工具,通过TCP网络协议实现数据…

抖音协议算法

以下是一些可能存在于社交媒体平台算法中的常见组成部分: 1. 用户兴趣模型:平台会根据用户的行为、喜好、关注的话题等信息,构建用户的兴趣模型。这可以通过分析用户的观看历史、点赞、评论、分享等行为来实现。 2. 内容特征提取&#xff1…

node.js基础--01

Author nodes:(题记) node.js is an open-source,cross-platform JAVAScript runtime environment。 node.js是一个开源,跨平台的js运行环境 common commands(常用指令) 1、C: enter hard …

C语言第十七弹---指针(一)

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 指针 1、内存和地址 1.1、内存 2、指针变量和地址 2.1、取地址操作符(&) 2.2、指针变量和解引用操作符(*)…

短剧小程序开发:打造高效、便捷的娱乐体验

随着移动互联网的普及和用户需求的多样化,短剧小程序作为一种新型的应用形态,逐渐受到了广大用户的青睐。短剧小程序开发旨在为用户提供一种高效、便捷的娱乐体验,让用户在忙碌的生活中轻松享受到精彩的短剧内容。本文将探讨短剧小程序开发的…

基于ssm的运动会管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式 🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 &…

Java玩转《啊哈算法》解密QQ号之队列

行有不得,反求诸己 文章目录 开头代码地址引子案例分析代码 队列封装升级演示 开头 各位好!本人在看《啊哈算法》,写的确实不错。 但略微遗憾的是,书籍示例代码是c语言,不是本人常用的Java。 那就弥补遗憾&#xff…

Linux 系统开始配置

文章目录 备份源为root 设置密码安装基本工具切换root 用户删除snap从 Ubuntu 移除 Snap 后使用 deb 文件安装软件商店和 Firefox在 Ubuntu 系统恢复到 Snap 软件包总结 删除 vim安装neovim在线安装neovim压缩安装neovim安装lazyvim安装剪切板 安装qt配置 Qt 环境不在sudoers文…

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

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

帮管客CRM 文件上传漏洞

免责声明:文章来源互联网收集整理,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该…

Linux实验记录:使用vsftpd服务传输文件

前言: 本文是一篇关于Linux系统初学者的实验记录。 参考书籍:《Linux就该这么学》 实验环境: VmwareWorkStation 17——虚拟机软件 RedHatEnterpriseLinux[RHEL]8——红帽操作系统 备注: 为了解决在多样复杂的设备之间解决传…

阿狸与小兔子的奇幻之旅

在很久很久以前,有一个遥远的国度,这个国度里生活着各种各样的动物,它们和谐共处,幸福快乐。在这个国度里,有一只聪明伶俐的小狐狸,名叫阿狸。 一天,阿狸在森林里散步时,遇到了一只正…

C++类和对象入门(二)

顾得泉:个人主页 个人专栏:《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂,年薪百万! 一、类的作用域 类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要…

亚马逊测评掉评、留不上评:问题根源与解决之道

亚马逊作为全球最大的电商平台之一,拥有数亿活跃用户和数百万卖家。在这个竞争激烈的市场中,产品评价对于卖家的成功至关重要。然而,许多卖家在尝试通过测评获取好评时,却遇到了掉评、留不上评的问题,这无疑增加了他们…

安装配置sqoop

一、了解Sqoop 1、Sqoop产生的原因 A. 多数使用hadoop技术的处理大数据业务的企业,有大量的数据存储在关系型数据中。 B. 由于没有工具支持,对hadoop和关系型数据库之间数据传输是一个很困难的事。 以上是sqoop产生的主要原因,也因此Sqoop主要用于hadoop与关系型数据库之…