我正在参加「掘金·启航计划」
Lottie 是什么
Lottie 是 Airbnb 开源的一个动画库,它支持 Android,iOS,React Native,Web,Windows,利用 json 文件的方式快速实现动画效果,所以,如果有复杂的动画,可以直接让设计出相关的动画 json 文件,可以大大减轻我们开发的工作量,这个只需设计师用 AE 设计动画,利用 bodymovin 导出,我们坐等动画 json 文件就行啦!
lottie 的项目地址:github.com/airbnb/lott…
加载动画
通过 assets 加载
添加依赖
implementation "com.airbnb.android:lottie:6.0.0"
将 UI 给你的 json 文件放到 app/src/main/assets 目录中
然后在 XML 中使用 LottieAnimationView 加载即可
<com.airbnb.lottie.LottieAnimationView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:lottie_autoPlay="true"
app:lottie_fileName="lottie_ani.json"
app:lottie_loop="true" />
我这个动画的 json 文件是在 lottie 官网下载的,传送门:lottiefiles.com/ ,效果如下:
也可以在代码中动态设置动画
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context=".MainActivity">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottieAnimationView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
binding.lottieAnimationView.apply {
setAnimation("lottie_ani.json")
repeatCount = LottieDrawable.INFINITE
playAnimation()
}
也可以使用 LottieCompositionFactory 加载
LottieCompositionFactory.fromAsset(this, "lottie_ani.json").addListener {
binding.lottieAnimationView.run {
setComposition(it)
repeatCount = LottieDrawable.INFINITE
playAnimation()
}
}
如果 Lottie 中有图片,只能通过下面这种方式加载,需要设置 imageAssetsFolder,程序会去 assets 目录下查找。这里指定的路径是 images/,则会去 assets/images/ 路径下寻找。
binding.lottieAnimationView.apply {
imageAssetsFolder = "images/lottie_img"
setAnimation("lottie_ani.json")
// 设置重复次数
repeatCount = LottieDrawable.INFINITE
playAnimation()
}
通过 URL 加载
这个网络链接的来源也是 Lottie 官网
binding.lottieAnimationView.apply {
setAnimationFromUrl("https://assets4.lottiefiles.com/packages/lf20_tSMENoX43Y.json")
repeatCount = LottieDrawable.INFINITE
playAnimation()
}
LottieCompositionFactory.fromUrl(
this, "https://assets4.lottiefiles.com/packages/lf20_tSMENoX43Y.json"
).addListener {
binding.lottieAnimationView.run {
setComposition(it)
repeatCount = LottieDrawable.INFINITE
playAnimation()
}
}
效果如下:
通过 raw 加载
我们也可以将本地的 json 文件放到 raw 目录下,raw 加载的功能比 assets 强大,支持 zip 包和 json 文件。
现在从官网里下载一个 zip 包,下载后解压就能看到一个 zip 包。
把它放入 raw 目录下
同样,有两种加载方式
binding.lottieAnimationView.apply {
setAnimation(R.raw.grass)
repeatCount = LottieDrawable.INFINITE
playAnimation()
}
LottieCompositionFactory.fromRawRes(this, R.raw.grass).addListener {
binding.lottieAnimationView.run {
setComposition(it)
repeatCount = LottieDrawable.INFINITE
playAnimation()
}
}
通过本地文件加载
binding.lottieAnimationView.apply {
try {
setAnimation(FileInputStream("${getExternalFilesDir(null)}/robot_ani.json"), null)
repeatCount = LottieDrawable.INFINITE
playAnimation()
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
}
LottieCompositionFactory.fromJsonInputStream(
FileInputStream("${getExternalFilesDir(null)}/robot_ani.json"), null
).addListener {
binding.lottieAnimationView.run {
setComposition(it)
repeatCount = LottieDrawable.INFINITE
playAnimation()
}
}
这里顺便总结一下 Android 的文件路径:
- context.filesDir:对应的路径为 /data/user/0/package_name/files
- context.cacheDir:对应的路径为 /data/user/0/package_name/cache
- context.externalCacheDir:对应的路径为 /storage/emulated/0/Android/data/package_name/cache
- context.getExternalFilesDir(type):对应的路径为 /storage/emulated/0/Android/data/package_name/files
- Environment.getExternalStorageDirectory():对应的路径为 /storage/emulated/0
- Environment.DIRECTORY_DOWNLOADS:对应的路径为 /storage/emulated/0/Download
动画控制
播放,取消,继续,暂停
// 播放
binding.lottieAnimationView.playAnimation()
// 取消
binding.lottieAnimationView.cancelAnimation()
// 继续
binding.lottieAnimationView.resumeAnimation()
// 暂停
binding.lottieAnimationView.pauseAnimation()
重复模式
binding.lottieAnimationView.repeatMode = LottieDrawable.RESTART //重新开始
binding.lottieAnimationView.repeatMode = LottieDrawable.REVERSE //反向
动画监听
binding.lottieAnimationView.addAnimatorListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator) {
// 动画开始时
}
override fun onAnimationEnd(animation: Animator) {
// 动画结束时
}
override fun onAnimationCancel(animation: Animator) {
// 动画取消时
}
override fun onAnimationRepeat(animation: Animator) {
// 动画重复时
}
})
如果你不想重写这么多的方法,也可以使用 AnimatorListenerAdapter,只需重写我们需要的即可。
binding.lottieAnimationView.addAnimatorListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator) {
// 动画开始时
}
override fun onAnimationEnd(animation: Animator) {
// 动画结束时
}
})
播放速度
默认为1,也可设置成小数。
binding.lottieAnimationView.speed = 0.5f
获取和设置帧
// 获取帧
val currentFrame = binding.lottieAnimationView.frame
// 设置帧
binding.lottieAnimationView.frame = 30