Jetpack Compose是谷歌在2019Google i/o大会上发布的新的库,一个用于构建原生Android UI的现代工具包。他有强大的工具和直观的Kotlin API,简化并加速了Android上的UI开发。可以帮助开发者用更少更直观的代码创建View,有更强大的功能,还能提高开发速度。
今天要和大家分享的是一个简单易用的Compose版骨架屏,笔者觉得用起来挺棒,大家可以看看。希望对大家的学习和工作有所帮助。
(PS:开源地址在文末)
骨架屏是页面的一个空白版本,通常会在页面完全渲染之前,通过一些灰色的区块大致勾勒出轮廓,待数据加载完成后,再替换成真实的内容。
骨架屏加载中效果,比起传统的加载中效果可以提供更多信息,用户体验更好,因此也变得越来越流行
本文主要介绍如何使用Compose实现一个简单易用的骨架屏效果
首先看下最终的效果图
第 1 步:在工程的build.gradle中添加:
allprojects {
repositories {
...
mavenCentral()
}
}
第2步:在应用的build.gradle中添加:
dependencies {
implementation 'io.github.shenzhen2017:shimmer:1.0.0'
}
@Composable
fun ShimmerSample() {
var loading: Boolean by remember {
mutableStateOf(true)
}
Column(
modifier = Modifier
.fillMaxWidth()
.shimmer(loading,config = ShimmerConfig())
) {
repeat(3) {
PlaceHolderItem()
Spacer(modifier = Modifier.height(10.dp))
}
}
}
如上所示:
具体主要有以下这些参数
data class ShimmerConfig(
// 未高亮部分颜色
val contentColor: Color = Color.LightGray.copy(alpha = 0.3f),
// 高亮部分颜色
val higLightColor: Color = Color.LightGray.copy(alpha = 0.9f),
// 渐变部分宽度
@FloatRange(from = 0.0, to = 1.0)
val dropOff: Float = 0.5f,
// 高亮部分宽度
@FloatRange(from = 0.0, to = 1.0)
val intensity: Float = 0.2f,
//骨架屏动画方向
val direction: ShimmerDirection = ShimmerDirection.LeftToRight,
//动画旋转角度
val angle: Float = 20f,
//动画时长
val duration: Float = 1000f,
//两次动画间隔
val delay: Float = 200f
)
如果我们要实现骨架屏效果,首先想到的是需要按照页面的结构再写一套UI,然后在加载中的时候,显示这套UI,否则隐藏
一般的加载中效果都是这样实现的,但这样会带来一个问题,不同的页面结构不同,那我们岂不是要一个页面就重写一套UI?这显然是不可接受的
我们可以想到,页面的结构其实我们已经写过一遍了,如果我们能复用我们写的页面结构不就好了吗?
我们可以通过图像混合模式来实现这一点
图像混合模式定义的是,当两个图像合成时,图像最终的展示方式。在Androd中,有相应的API接口来支持图像混合模式,即Xfermode.
图像混合模式主要有以下16种,以下这张图片从一定程度上形象地说明了图像混合的作用,两个图形一圆一方通过一定的计算产生不同的组合效果,具体如下
我们介绍几个常用的,其它的感兴趣的同学可自行查阅
如果我们把页面的UI结构作为目标图像,骨架屏效果作为源图像,然后使用SRC_IN混合模式,就可以实现只在页面的结构上显示骨架屏,在空白部分不显示,这样就可以避免重复写UI了
上面我们已经实现了在页面结构上显示骨架屏,但是骨架屏效果还有一个动画效果
其实也很简单,给骨架屏设置一个渐变效果,然后做一个平移动画,然后看起来就是现在的骨架屏闪光动画了
fun Modifier.shimmer(): Modifier = composed {
var progress: Float by remember { mutableStateOf(0f) }
val infiniteTransition = rememberInfiniteTransition()
progress = infiniteTransition.animateFloat().value // 动画效果,计算百分比
ShimmerModifier(visible = visible, progress = progress, config = config)
}
internal class ShimmerModifier(progress:Float) : DrawModifier, LayoutModifier {
private val paint = Paint().apply {
blendMode = BlendMode.SrcIn //设置混合模式
shader = LinearGradientShader(Offset(0f, 0f),toOffset,colors,colorStops)//设置渐变色
}
override fun ContentDrawScope.draw() {
drawContent()
val (dx, dy) = getOffset(progress) //根据progress,设置平移的位置
paint.shader?.postTranslate(dx, dy) // 平移操作
it.drawRect(Rect(0f, 0f, size.width, size.height), paint = paint)//绘制骨架屏效果
}
}
如上所示,主要是几步:
上面介绍了我们提供了一些参数,可以自定义骨架屏的效果,其它参数都比较好理解,主要是以下两个参数有点难理解
我们知道,可以通过contentColor自定义普通部分颜色,higLightColor自定义高亮部分颜色
但是这两种颜色是如何分布的呢?渐变的比例是怎样的呢?可以看下下面的代码:
private val paint = Paint().apply {
shader = LinearGradientShader(Offset(0f, 0f),toOffset,colors,colorStops)//设置渐变色
}
private val colors = listOf(
config.contentColor,
config.higLightColor,
config.higLightColor,
config.contentColor
)
private val colorStops: List = listOf(
((1f - intensity - dropOff) / 2f).coerceIn(0f, 1f),
((1f - intensity - 0.001f) / 2f).coerceIn(0f, 1f),
((1f + intensity + 0.001f) / 2f).coerceIn(0f, 1f),
((1f + intensity + dropOff) / 2f).coerceIn(0f, 1f)
)
可以看出,我们的颜色渐变有以下特点:
在实现Compose版本骨架屏的过程中,主要借鉴了以下开源框架的思想,有兴趣的同学也可以了解下
Facebook开源的shimmer-android
Habib Kazemi开源的compose-shimmer
简单易用的Compose版骨架屏
开源不易,如果项目对你有所帮助,欢迎点赞,Star,收藏~
整理总目录
为什么我们需要一个新的UI 工具?
Jetpack Compose的着重点
加速开发
强大的UI工具
直观的Kotlin API
API 设计
Compose API 的原则
一切都是函数
顶层函数(Top-level function)
组合优于继承
信任单一来源
深入了解Compose
Core
Foundation
Material
插槽API
Android Jetpack Compose 最全上手指南
Jetpack Compose 环境准备和Hello World
布局
使用Material design 设计
Compose 布局实时预览
……
深入详解 Jetpack Compose | 优化 UI 构建
Compose 所解决的问题
Composable 函数剖析
声明式 UI
组合 vs 继承
封装
重组
……
深入详解 Jetpack Compose | 实现原理
@Composable 注解意味着什么?
执行模式
Positional Memoization (位置记忆化)
存储参数
重组
……
Jetpack Compose应用1
开始前的准备
创建DEMO
遇到的问题
Jetpack Compose应用2
Jetpack Compose应用做一个倒计时器
数据结构
倒计时功能
状态模式
Compose 布局
绘制时钟
用Jetpack Compose写一个玩安卓App
准备工作
引入依赖
新建 Activity
创建 Compose
PlayTheme
画页面
底部导航栏
管理状态
添加页面
用Compose Android 写一个天气应用
开篇
画页面
画背景
画内容
……
用Compose快速打造一个“电影App”
成品
实现方案
实战
不足
……
有需要的朋友可以【扫描下方二维码】直接找我免费领取。
希望这份资料可以给想了解、学习、应用Android Jetpack Compose的小伙伴一个参考。