使用Jetpack Compose实现具有多选功能的图片网格

使用Jetpack Compose实现具有多选功能的图片网格

在现代应用中,多选功能是一项常见且重要的需求。例如,Google Photos允许用户轻松选择多个照片进行分享、添加到相册或删除。在本文中,我们将展示如何使用Jetpack Compose实现类似的多选行为,最终效果如下:
图片网格多选功能效果图

主要步骤

  1. 实现基本网格
  2. 为网格元素添加选择状态
  3. 添加手势处理,实现拖动选择/取消选择元素
  4. 完善界面,使元素看起来像照片

实现基本网格

首先,我们使用LazyVerticalGrid实现基本网格,使应用能够在所有屏幕尺寸上良好运行。较大屏幕显示更多列,较小屏幕显示更少列。以下代码展示了如何实现一个简单的网格:

@Composable
private fun PhotoGrid() {val photos by rememberSaveable { mutableStateOf(List(100) { it }) }LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 128.dp),verticalArrangement = Arrangement.spacedBy(3.dp),horizontalArrangement = Arrangement.spacedBy(3.dp)) {items(photos, key = { it }) {Surface(tonalElevation = 3.dp,modifier = Modifier.aspectRatio(1f)) {}}}
}

在这里,我们使用LazyVerticalGrid创建一个自适应的网格,并使用PhotoItem来展示每个元素。尽管目前只是显示一个简单的有色Surface,但我们已经有了一个可以滚动的网格。
基本网格

添加选择状态

为了实现多选功能,我们需要追踪当前选中的元素及是否处于选择模式,并使网格元素反映这些状态。首先,将网格元素提取为独立的可组合项PhotoItem,并反映其选择状态:

@Composable
private fun ImageItem(selected: Boolean, inSelectionMode: Boolean, modifier: Modifier
) {Surface(tonalElevation = 3.dp,contentColor = MaterialTheme.colorScheme.primary,modifier = modifier.aspectRatio(1f)) {if (inSelectionMode) {if (selected) {Icon(Icons.Default.CheckCircle, null)} else {Icon(Icons.Default.RadioButtonUnchecked, null)}}}
}


这个可组合项根据传入的状态显示不同的图标。当用户点击一个元素时,我们将其ID添加或移除到选中集合中,并根据选中集合的状态确定是否处于选择模式:

@Composable
private fun PhotoGrid() {val photos by rememberSaveable { mutableStateOf(List(100) { it }) }val selectedIds = rememberSaveable { mutableStateOf(emptySet<Int>()) } // NEWval inSelectionMode by remember { derivedStateOf { selectedIds.value.isNotEmpty() } } // NEWLazyVerticalGrid(columns = GridCells.Adaptive(minSize = 128.dp),verticalArrangement = Arrangement.spacedBy(3.dp),horizontalArrangement = Arrangement.spacedBy(3.dp)) {items(photos, key = { it }) { id ->val selected = selectedIds.value.contains(id) // NEWImageItem(selected, inSelectionMode, Modifier.clickable { // NEWselectedIds.value = if (selected) {selectedIds.value.minus(id)} else {selectedIds.value.plus(id)}})}}
}

添加手势处理

现在我们追踪了选中状态,可以实现手势处理来增加和移除选中的元素。我们的需求如下:

  1. 通过长按进入选择模式
  2. 长按后拖动以选择或取消选择从起点到终点的所有元素
  3. 在选择模式下,点击元素以选择或取消选择它们
  4. 长按已选中的元素不执行任何操作

为了处理这些手势,我们需要在网格中添加手势处理,而不是在单个元素中添加。我们使用LazyGridState和拖动位置来检测当前指针指向的元素:

@Composable
private fun PhotoGrid() {val photos by rememberSaveable { mutableStateOf(List(100) { it }) }val selectedIds = rememberSaveable { mutableStateOf(emptySet<Int>()) }val inSelectionMode by remember { derivedStateOf { selectedIds.value.isNotEmpty() } }val state = rememberLazyGridState() // NEWLazyVerticalGrid(state = state, // NEWcolumns = GridCells.Adaptive(minSize = 128.dp),verticalArrangement = Arrangement.spacedBy(3.dp),horizontalArrangement = Arrangement.spacedBy(3.dp),modifier = Modifier.photoGridDragHandler(state, selectedIds) // NEW) {//..}
}

在上述代码中,我们使用pointerInput修饰符和detectDragGesturesAfterLongPress方法设置拖动处理。我们在onDragStart中设置初始元素,在onDrag中更新当前指针指向的元素。

fun Modifier.photoGridDragHandler(lazyGridState: LazyGridState,selectedIds: MutableState<Set<Int>>
) = pointerInput(Unit) {var initialKey: Int? = nullvar currentKey: Int? = nulldetectDragGesturesAfterLongPress(onDragStart = { offset -> .. },onDragCancel = { initialKey 

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

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

相关文章

查看Windows启动时长

&#xff08;附图片&#xff09;电脑自带检测开机时长---查看方式_电脑开机时长命令-CSDN博客 eventvwr - Windows日志 - 系统 - 查找 - 6013.jpg

如何利用ChatGPT改善日常生活:一个普通人的指南

当你打开 ChatGPT&#xff0c;显现的是一个简洁的聊天界面。 许多人利用 ChatGPT 进行日常对话。 然而&#xff0c;ChatGPT 的功能远不止于此。 对话只是其众多能力中的一种&#xff0c;如果仅将其视为高级版的聊天机器人&#xff0c;那未免低估了它。 AI 在信息处理方面的…

VMware ESXi 8.0U3 macOS Unlocker OEM BIOS 集成驱动版,新增 12 款 I219 网卡驱动

VMware ESXi 8.0U3 macOS Unlocker & OEM BIOS 集成驱动版&#xff0c;新增 12 款 I219 网卡驱动 VMware ESXi 8.0U3 macOS Unlocker & OEM BIOS 集成网卡驱动和 NVMe 驱动 (集成驱动版) 发布 ESXi 8.0U3 集成驱动版&#xff0c;在个人电脑上运行企业级工作负载 请访…

ETAS工具导入DEXT生成Dcm及Dem模块(二)

文章目录 前言DcmDcmDsdDcmDslDcmDspDcmPageBufferCfgDem报错解决总结前言 之前一篇文章介绍了导入DEXT之后在cfggen之前的更改,cfggen完成之后,就可以生成dcm,dem的配置了,但生成完配置后,如果直接生成BSW代码,会报错。本文介绍在cfggen完成后,生成BSW代码前的修改 Dc…

哈尔滨高校大学智能制造实验室数字孪生可视化系统平台项目的验收

哈尔滨高校大学智能制造实验室数字孪生可视化系统平台项目的验收&#xff0c;标志着这一技术在教育领域的应用取得了新的突破。项目旨在开发一个数字孪生可视化系统平台&#xff0c;用于哈尔滨高校大学智能制造实验室的设备模拟、监测与数据分析。项目的主要目标包括&#xff1…

【算法专题--链表】两数相加 -- 高频面试题(图文详解,小白一看就懂!!)

目录 一、前言 二、题目描述 三、解题方法 ⭐双指针 -- 模拟进位 (使用哨兵位头节点) &#x1f95d; 什么是哨兵位头节点&#xff1f; &#x1f347;思路解析 &#x1f34d;案例图解 四、总结与提炼 五、共勉 一、前言 两数相加 这道题&#xff0c;可以说是--…

SpringCloud Alibaba Seata2.0分布式事务AT模式实践总结

这里我们划分订单、库存与支付三个module来实践Seata的分布式事务。 依赖版本(jdk17)&#xff1a; <spring.boot.version>3.1.7</spring.boot.version> <spring.cloud.version>2022.0.4</spring.cloud.version> <spring.cloud.alibaba.version>…

计算机监控软件有哪些?10款常年霸榜的计算机监控软件

计算机监控软件是企业管理和保护信息安全的重要工具&#xff0c;它们帮助企业管理者监督员工的计算机使用行为&#xff0c;确保工作效率、数据安全以及合规性。在众多监控软件中&#xff0c;有些产品因其卓越的功能、易用性、安全性以及持续获得的良好市场反馈而常年占据行业领…

C++——探索智能指针的设计原理

前言: RAII是资源获得即初始化&#xff0c; 是一种利用对象生命周期来控制程序资源地手段。 智能指针是在对象构造时获取资源&#xff0c; 并且在对象的声明周期内控制资源&#xff0c; 最后在对象析构的时候释放资源。注意&#xff0c; 本篇文章参考——C 智能指针 - 全部用法…

IBCS 虚拟专线——让企业用于独立IP

在当今竞争激烈的商业世界中&#xff0c;企业的数字化运营对网络和服务器的性能有着极高的要求。作为一家企业的 IT 主管&#xff0c;我深刻体会到了在网络和服务器配置方面所面临的种种挑战&#xff0c;以及 IBCS 虚拟专线带来的革命性改变。 我们企业在业务扩张的过程中&…

msvcr120.dll文件下载的高级教程,修复msvcr120.dll 详细步骤分享

当电脑系统或特定应用程序无法找到或访问到msvcr120.dll文件时&#xff0c;便会导致错误消息的出现&#xff0c;例如“找不到 msvcr120.dll”、“msvcr120.dll丢失”等。这篇文章将大家讨论关于msvcr120.dll文件的内容、msvcr120.dll丢失问题的解决方法&#xff0c;其中最常见的…

web使用cordova打包Andriod

一.安装Gradel 1.下载地址 Gradle Distributions 2.配置环境 3.测试是否安装成功 在cmd gradle -v 二.创建vite项目 npm init vitelatest npm install vite build 三.创建cordova项目 1.全局安装cordova npm install -g cordova 2. 创建项目 cordova create cordova-app c…

VuePress日常使用

本篇来讲解下更多关于 VuePress 的基本用法 ‍ 配置首页 现在的页面太简单了&#xff0c;我们可以对项目首页进行配置&#xff0c;修改 docs/README.md &#xff08;这些配置是什么后面会说&#xff09;&#xff1a; --- home: true heroImage: https://s3.bmp.ovh/imgs/20…

Mac可以读取NTFS吗 Mac NTFS软件哪个好 mac ntfs读写工具免费

在跨操作系统环境下使用外部存储设备时&#xff0c;特别是当Windows系统的U盘被连接到Mac电脑时&#xff0c;常常会遇到文件系统兼容性的问题。由于Mac OS原生并不完全支持对NTFS格式磁盘的读写操作&#xff0c;导致用户无法直接在Mac上向NTFS格式的U盘或硬盘写入数据。下面我们…

揭示隐藏的模式:秩和检验和单因素方差分析的实战指南【考题】

1.研究一种新方法对于某实验结果准确性提高的效果&#xff0c;并将其与原有方法进行比较&#xff0c;结果见下表&#xff0c;请评价两者是否有不同? (行无序&#xff0c;列有序)-->单方向有序-->两独立样本的秩和检验) 如下图所示&#xff0c;先将相关数据导入spss。 图…

什么是指令微调(LLM)

经过大规模数据预训练后的语言模型已经具备较强的模型能力&#xff0c;能够编码丰富的世界知识&#xff0c;但是由于预训练任务形式所限&#xff0c;这些模型更擅长于文本补全&#xff0c;并不适合直接解决具体的任务。 指令微调是相对“预训练”来讲的&#xff0c;预训练的时…

SpringBoot3基础用法

技术和工具「!喜新厌旧」 一、背景 最近在一个轻量级的服务中&#xff0c;尝试了最新的技术和工具选型&#xff1b; 即SpringBoot3&#xff0c;JDK17&#xff0c;IDEA2023&#xff0c;Navicat16&#xff0c;虽然新的技术和工具都更加强大和高效&#xff0c;但是适应采坑的过程…

企业网络安全必知的三大访问控制模型

在当今信息化社会中&#xff0c;信息系统的安全性成为了组织和个人关注的焦点。随着信息技术的不断发展和应用&#xff0c;信息系统的复杂性和规模不断扩大&#xff0c;系统中存储和处理的信息量也日益增长。 一、引言 在当今信息化社会中&#xff0c;信息系统的安全性成为了组…

【知识点篇]《计算机组成原理》之计算机系统概述

1.1 计算机发展历程 世界上第一台电子数字计算机 1946年&#xff0c;ENIAC(Electronic Numerical Integrator And Computer)在美国宾夕法尼亚大学研制成功。性能低&#xff0c;耗费巨大&#xff0c;但却是科学史上的一次划时代的创新&#xff0c;奠定了电子计算机的基础&#x…

stm32学习笔记---ADC模数转换器(理论部分)

目录 ADC简介 什么叫逐次逼近型&#xff1f; STM32 ADC框图 模数转换器外围线路 ADC基本结构图 输入通道 规则组的四种转换模式 第一种&#xff1a;单次转换非扫描模式 第二种&#xff1a;连续转换&#xff0c;非扫描模式 第三种&#xff1a;单次转换&#xff0c;扫描…