安卓Compose实现鱼骨加载中效果

安卓Compose实现鱼骨加载中效果

文章目录

  • 安卓Compose实现鱼骨加载中效果
    • 背景与简介
    • 适用场景
    • Compose骨架屏与传统View实现对比
    • Shimmer动画原理简介
    • 常见问题与优化建议
    • 参考资料

本文首发地址 https://h89.cn/archives/404.html

背景与简介

在移动应用开发中,加载中占位动画(Skeleton/骨架屏)能够有效提升用户体验,减少因数据延迟带来的焦虑感。鱼骨加载效果是一种常见的骨架屏动画,模拟内容结构,配合闪烁动画(Shimmer)让界面在数据加载时更具活力。Jetpack Compose 作为 Android 现代声明式UI框架,极大简化了骨架屏实现难度。

适用场景

  • 网络请求数据加载时的占位
  • 列表、卡片等内容结构明确的页面
  • 需要提升加载体验的场景

Compose骨架屏与传统View实现对比

  • 传统View实现骨架屏通常需要自定义View、手动绘制、管理动画,代码复杂且维护成本高。
  • Compose下,借助第三方库如 compose-shimmer,仅需简单修饰符组合即可实现灵活的骨架屏动画,代码更简洁、可读性更强。

Shimmer动画原理简介

Shimmer是一种通过渐变色块横向移动,模拟光影流动的动画效果。其本质是利用Canvas绘制渐变蒙版,并通过属性动画不断平移,实现闪烁流动的视觉效果。compose-shimmer库对这一过程进行了高度封装,开发者只需一行Modifier即可应用。

安卓如何实现如下图类似鱼骨加载中效果

我们需要使用compose-shimmer,添加依赖 (build.gradle)
implementation("com.valentinilk.shimmer:compose-shimmer:1.3.2")

最新的版本号可以参见 https://github.com/valentinilk/compose-shimmer

定义一个状态类 UiState 用于管理加载状态和数据:

data class UiState(val isLoading: Boolean = true, // 控制是否处于加载状态val data: List<Order> = emptyList() // 实际数据列表
) : IState

UiState 包含了 isLoading 布尔值来指示当前是否正在加载数据,以及 data 列表来存储实际的订单数据。当 isLoadingtrue 时,UI 将显示占位符(鱼骨效果),否则显示实际数据。

LazyColumn 中根据 UiStateisLoading 状态来显示不同的内容:

isLoadingtrue 时,我们渲染固定数量的占位符(这里是5个),并传入空的字符串作为占位内容。这些占位符将通过 OrderItemView 应用鱼骨加载效果。

isLoadingfalse 时,我们渲染实际的 viewState.data 中的数据。

LazyColumn(modifier = Modifier.padding(horizontal = 16.dp),verticalArrangement = Arrangement.spacedBy(16.dp)
) {if (viewState.isLoading) {items(5) { index ->// 传入空的字符占位OrderItemView(order = Order(type = "              ",status = "          ",time = "                                   ",startAddress = "                                        ",endAddress = "                                         "),viewState = viewState)}} else {items(viewState.data.size) { index ->OrderItemView(order = viewState.data[index],viewState = viewState)}}
}

OrderItemView 的部分参考实现如下:

OrderItemView 是一个可组合函数,它根据 viewState.isLoading 的值来决定是显示鱼骨加载效果还是实际的订单信息。关键在于 Modifier.shimmer() 的应用。


@Composable
fun OrderItemView(order: Order, viewState: UiState) {// 通过 viewState.isLoading 控制显示Card(modifier = Modifier.fillMaxWidth().padding(vertical = 10.dp).then(if (viewState.isLoading) Modifier.shimmer() else Modifier),shape = RoundedCornerShape(16.dp),elevation = CardDefaults.cardElevation(4.dp),colors = CardDefaults.cardColors(containerColor = Color.White)) {// 部分实现, 通过 viewState.isLoading 控制显示Text(modifier = Modifier.background(color = if (viewState.isLoading) Color.LightGray else Color.Transparent,shape = RoundedCornerShape(2.dp)).then(if (viewState.isLoading) Modifier.shimmer() else Modifier), // shimmer 作用在 Text 上,使其背景闪烁text = order.type,style = MaterialTheme.typography.titleMedium)}
}

常见问题与优化建议

  • 闪烁效果不明显?
    • 请确保 Modifier.shimmer() 应用在 background 等绘制修饰符之后。
    • 可调整骨架色(如 Color.LightGray)和Shimmer参数(如高亮色、动画速度)增强对比度。
  • 骨架屏与内容跳变明显?
    • 建议骨架屏布局与实际内容布局保持一致,避免切换时界面抖动。
  • 性能影响?
    • compose-shimmer 性能较优,但大量骨架项或复杂动画时建议限制骨架数量,避免过度绘制。
  • 自定义骨架形状?
    • 可通过 backgroundshape 参数自定义圆角、椭圆等形状,灵活适配不同UI风格。

参考资料

  • compose-shimmer官方文档:https://github.com/valentinilk/compose-shimmer
  • Jetpack Compose官方文档:https://developer.android.com/jetpack/compose
  • 完整代码实现: https://gitee.com/chenjim/ArchitectureMVI 中 ShimmerScreen.kt

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

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

相关文章

基于C++处理Modbus报文的完整指南

目录 &#x1f4e6; 一、Modbus报文结构解析1. RTU模式帧格式2. TCP模式帧格式 &#x1f527; 二、C实现方案与库选择示例1&#xff1a;libmodbus读取保持寄存器 (TCP) ⚙️ 三、核心处理技术1. 报文构建与发送2. 响应解析与错误处理3. 数据类型转换 &#x1f680; 四、高级应用…

【性能调优系列】深入解析火焰图:从基础阅读到性能优化实战

博客目录 一、火焰图基础&#xff1a;结构与阅读方法二、深入分析火焰图&#xff1a;关键观察点与性能瓶颈识别1. 识别最宽的函数块2. HTTP 请求处理分析3. 数据库操作分析4. 业务逻辑分析 三、性能优化实战&#xff1a;从火焰图到解决方案1. 线程池性能优化2. 数据库访问优化3…

基于 OpenCV 和 DLib 实现面部特征调整(眼间距、鼻子、嘴巴)

摘 要 本文介绍如何利用Dlib面部特征点检测和OpenCV图像处理技术&#xff0c;通过Python实现面部特征的精准调整。我们将以改变眼间距为例&#xff0c;演示包括地标检测、三角剖分变形等关键技术&#xff0c;该方法可扩展至嘴唇、眉毛等面部特征的调整。 技术栈 Python 3.8 …

Spring Data Redis 实战指南

Spring Data Redis 核心特性 Spring Data Redis 是基于 Redis 的 NoSQL 内存数据结构存储解决方案,为 Spring 应用程序提供与 Redis 交互的高级抽象层。其核心架构设计体现了对现代应用需求的深度适配,主要技术特性可归纳为以下维度: 数据结构支持体系 作为多模型数据存储…

AI IDE 正式上线!通义灵码开箱即用

近期&#xff0c;通义灵码AI IDE正式上线&#xff0c;即日起用户可在通义灵码官网免费下载开箱即用。 作为AI原生的开发环境工具&#xff0c;通义灵码AI IDE深度适配了最新的千问3大模型&#xff0c;并全面集成通义灵码插件能力&#xff0c;具备编程智能体、行间建议预测、行间…

如何搭建Z-Blog PHP版本:详细指南

Z-Blog是一款功能强大且易于使用的博客平台&#xff0c;支持PHP和ASP两种环境。本文将重点介绍如何在PHP环境下搭建Z-Blog博客系统&#xff0c;帮助您快速上线自己的个人博客站点。 准备工作 1. 获取Z-Blog PHP版本 首先&#xff0c;访问Z-Blog官方网站下载最新版本的Z-Blog…

App使用webview套壳引入h5(二)—— app内访问h5,顶部被手机顶部菜单遮挡问题,保留顶部安全距离

引入webview的页面添加safeAreaInsets&#xff0c;对weview的webviewStyles做处理 在myApp中改造 entry.vue代码如下 template><view class"entry-page" :style"{ paddingTop: safeAreaInsets.top px }"><web-view :webview-styles"we…

机器学习:支持向量机(SVM)原理解析及垃圾邮件过滤实战

一、什么是支持向量机&#xff08;SVM&#xff09; 1. 基本概念 1.1 二分类问题的本质 在机器学习中&#xff0c;分类问题是最常见的任务之一。最简单的情况就是二分类&#xff1a;比如一封邮件是“垃圾邮件”还是“正常邮件”&#xff1f;一个病人是“患病”还是“健康”&a…

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…

STM32中自动生成Flash地址的方法

每页大小为 2KB(0x800 字节),地址间隔为 0x800 总地址空间覆盖范围:0x08000000 ~ 0x0803F800(共 256KB) 适用于 STM32 大容量 / 中容量产品(如 F103 系列) 代码如下 // 通用定义(需根据实际页大小调整) #define FLASH_BASE_ADDR 0x08000000 #define FLASH_PAGE_SIZ…

(12)java+ selenium->元素定位大法之By_link_text

1.简介 本章节介绍元素定位中的link_text,顾名思义是通过链接定位的(官方说法:超链接文本定位)。什么是link_text呢,就是我们在任何一个网页上都可以看到有一个或者多个链接,上面有一个文字描述,点击这个文字,就可以跳转到其他页面。这个就是link_Text。 注意:link_t…

Tomcat 线程模型详解性能调优

1. Tomcat I/O模型详解**&#xff08;了解&#xff09;** 1.1 Linux I/O模型详解 I/O要解决什么问题 I/O&#xff1a;在计算机内存与外部设备之间拷贝数据的过程。 程序通过CPU向外部设备发出读指令&#xff0c;数据从外部设备拷贝至内存需要一段时间&#xff0c;这段时间CPU就…

C++课设:智能优惠快餐点餐系统

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 专栏介绍&#xff1a;《编程项目实战》 目录 一、项目介绍与亮点功能1. 项目背景2.完…

PHP的namespace

文章目录 环境Java的packagepackage关键字包结构和目录结构访问权限import关键字总结 PHP的namespacenamespace关键字在同一个文件里使用资源限定&#xff0c;完全限定&#xff0c;非限定限定完全限定非限定 use关键字use VS 直接指定资源在不同的文件里使用总结 环境 Windows…

矩阵分解相关知识点总结(二)

文章目录 三、矩阵的QR分解3.1、Givens矩阵与Givens变换3.2、Householder矩阵与Householder变换3.3、QR分解 书接上文矩阵分解相关知识点总结&#xff08;一&#xff09; 三、矩阵的QR分解 3.1、Givens矩阵与Givens变换 设非零列向量 x ∈ R n \bm{x}\in {\bf{R}}^n x∈Rn及单…

Chorme如何对于youtube视频进行画中画背景播放?

画中画可以让你小窗播放&#xff0c;然后浏览器放后台还可以做点别的事情。 B站直接可以选择小窗播放&#xff0c;游览器最小化就可以&#xff0c;但是youtube的小窗播放游览器一切换就不显示了。 其实是因为youtube的小窗播放不是真的小窗播放。要想真的实现需要在youtube视…

14.AI搭建preparationのBERT预训练模型进行文本分类

一、回顾&#xff1a; 对深度学习框架Python2.0进行自然语言处理有了一个基础性的认识注意力模型编码器(encoder_layer,用于分类的全连接层dense_layer)&#xff0c;抛弃了传统的循环神经网络和卷积神经网络&#xff0c;通过注意力模型将任意位置的两个单词的距离转换成1编码器…

OD 算法题 B卷【最长公共前缀】

文章目录 最长公共前缀 最长公共前缀 编写一个函数来查找字符串数组 中的最长公共前缀&#xff0c;如果不存在公共前缀&#xff0c;返回字符串’Zero’字符串长度范围【2,1000】&#xff0c;字符串中字符长度范围为【1,126】 示例1 输入&#xff1a; [“flower”, “flow”, …

pycharm F2 修改文件名 修改快捷键

菜单&#xff1a;File-> Setting&#xff0c; Keymap中搜索 Rename&#xff0c; 其中&#xff0c;有 Refactor-> Rename&#xff0c;右键添加快捷键&#xff0c;F2&#xff0c;删除原有快捷键就可以了。

WEB安全--SQL注入--bypass技巧2

继之前文章的补充&#xff1a; WEB安全--SQL注入--bypass技巧_sql注入过滤空格-CSDN博客 Q1&#xff1a;发现sql注入的时间盲注时&#xff0c;如果时间盲注的函数都被过滤了&#xff0c;怎么办&#xff1f; 除了找其他函数替换、编码等方式&#xff0c;还有以下方式绕过&…