掌握 MotionLayout:交互动画开发
前言
在 Android 开发中,系统自带的属性动画(如 ObjectAnimator
和 ValueAnimator
)虽然功能强大,但在复杂动画场景下,第三方动画库能提供更高效的开发体验和更丰富的效果。本文将深入解析 Lottie、MotionLayout、AndroidViewAnimations、Rebound 等热门第三方动画库,提供详细的代码实现、对比分析及关键点总结,助力开发者快速选择合适的工具。
一、Lottie(Airbnb)
定位:复杂矢量动画(JSON 格式)的渲染引擎,适合加载动画、复杂交互动画。
对比:相比传统帧动画(AnimationDrawable
),Lottie 的 JSON 动画体积更小、可编辑性更强,且支持动态修改属性。
1. 使用步骤与代码实现
1.1 添加依赖
// build.gradle (Module)
dependencies {implementation 'com.airbnb.android:lottie:6.1.0' // 使用最新版本
}
1.2 准备动画资源
- 从 LottieFiles 下载 JSON 文件,或通过 Adobe After Effects 导出。
- 将 JSON 文件放入
res/raw
目录(如loading.json
)。
1.3 XML 布局配置
<com.airbnb.lottie.LottieAnimationViewandroid:id="@+id/lottie_view"android:layout_width="200dp"android:layout_height="200dp"app:lottie_rawRes="@raw/loading"app:lottie_loop="true"app:lottie_autoPlay="false" />
1.4 代码控制动画
val lottieView = findViewById<LottieAnimationView>(R.id.lottie_view)// 播放动画
lottieView.playAnimation()// 暂停动画
lottieView.pauseAnimation()// 动态修改颜色(Kotlin 扩展函数)
lottieView.setAnimation("loading.json")
lottieView.setColorFilterToLayer("icon_layer", Color.RED)// 监听动画事件
lottieView.addAnimatorListener(object : Animator.AnimatorListener {override fun onAnimationStart(animation: Animator) {}override fun onAnimationEnd(animation: Animator) {}override fun onAnimationCancel(animation: Animator) {}override fun onAnimationRepeat(animation: Animator) {}
})
2. 关键点总结
- 优点:
- 支持 After Effects 复杂动画,设计师可直接参与开发。
- 高性能渲染,支持硬件加速。
- 缺点:
- JSON 文件可能较大,需压缩优化。
- 动态修改部分属性需通过代码实现。
- 适用场景:启动页动画、复杂图标动效、动态插画。
二、MotionLayout(Google)
定位:基于 ConstraintLayout
的布局过渡动画库,适合实现视图间的平滑切换效果。
对比:相比传统属性动画,MotionLayout 直接在 XML 中定义动画逻辑,减少代码量,且支持触摸交互。
1. 使用步骤与代码实现
2.1 添加依赖
dependencies {implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
}
2.2 定义 MotionScene 文件
- 创建
res/xml/scene_login.xml
,定义起始和结束布局状态:
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><Transitionapp:constraintSetStart="@id/collapsed"app:constraintSetEnd="@id/expanded"app:duration="1000"><OnClick app:targetId="@id/button_expand" /></Transition><!-- 初始状态:折叠 --><ConstraintSet android:id="@+id/collapsed"><Constraintandroid:id="@id/header"android:layout_width="match_parent"android:layout_height="100dp"app:layout_constraintTop_toTopOf="parent" /></ConstraintSet><!-- 结束状态:展开 --><ConstraintSet android:id="@+id/expanded"><Constraintandroid:id="@id/header"android:layout_width="match_parent"android:layout_height="300dp"app:layout_constraintTop_toTopOf="parent" /></ConstraintSet>
</MotionScene>
2.3 在布局中关联 MotionScene
<androidx.constraintlayout.motion.widget.MotionLayoutandroid:id="@+id/motion_layout"android:layout_width="match_parent"android:layout_height="match_parent"app:layoutDescription="@xml/scene_login"><Viewandroid:id="@+id/header"android:background="#FF5722" /><Buttonandroid:id="@+id/button_expand"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>
2.4 代码控制过渡动画
val motionLayout = findViewById<MotionLayout>(R.id.motion_layout)// 动态切换动画状态
motionLayout.transitionToEnd() // 切换到结束状态
motionLayout.transitionToStart() // 切换回初始状态// 监听动画进度
motionLayout.setTransitionListener(object : MotionLayout.TransitionListener {override fun onTransitionStarted(layout: MotionLayout, startId: Int, endId: Int) {}override fun onTransitionChange(layout: MotionLayout, progress: Float) {}override fun onTransitionCompleted(layout: MotionLayout, currentId: Int) {}override fun onTransitionTrigger(layout: MotionLayout, triggerId: Int, positive: Boolean, progress: Float) {}
})
2. 关键点总结
- 优点:
- 在 XML 中完成复杂动画定义,减少代码耦合。
- 支持触摸拖动交互(如抽屉菜单展开)。
- 缺点:
- 学习成本较高,需熟悉
ConstraintSet
和Transition
。 - 不适合非布局属性的动画(如颜色渐变)。
- 学习成本较高,需熟悉
- 适用场景:页面转场、可折叠布局、交互式视图动画。
三、AndroidViewAnimations(daimajia)
定位:提供预定义视图动画(如弹跳、淡入淡出),快速实现常见动效。
对比:相比系统 ViewPropertyAnimator
,API 更简洁,但灵活性较低。
1. 使用步骤与代码实现
3.1 添加依赖
dependencies {implementation 'com.daimajia.androidanimations:library:2.4@aar'
}
3.2 代码中使用预定义动画
import com.daimajia.androidanimations.library.Techniques
import com.daimajia.androidanimations.library.YoYo// 弹跳动画
YoYo.with(Techniques.Bounce).duration(1000).repeat(2).playOn(view)// 渐入动画
YoYo.with(Techniques.FadeIn).duration(500).playOn(view)// 自定义插值器
YoYo.with(Techniques.Pulse).duration(1000).interpolate(AccelerateDecelerateInterpolator()).playOn(view)
2. 关键点总结
- 优点:
- 一行代码实现常见动画,开发效率极高。
- 支持链式调用,可配置重复次数、插值器等。
- 缺点:
- 无法自定义动画属性(如缩放比例、旋转角度)。
- 库已停止更新,兼容性需测试。
- 适用场景:快速实现简单动效(如按钮点击反馈)。
四、Rebound(Facebook)
定位:基于弹簧物理模型的动画库,适合实现弹性效果。
对比:相比系统 SpringAnimation
,Rebound 提供更精细的物理参数控制。
1. 使用步骤与代码实现
4.1 添加依赖
dependencies {implementation 'com.facebook.rebound:rebound:0.3.8'
}
4.2 代码示例:弹性缩放
val springSystem = SpringSystem.create()
val spring = springSystem.createSpring()// 配置弹簧参数
spring.springConfig = SpringConfig.fromOrigamiTensionAndFriction(100.0, 10.0)// 监听弹簧值变化
spring.addListener(object : SpringListener {override fun onSpringUpdate(spring: Spring) {val value = spring.currentValue.toFloat()view.scaleX = valueview.scaleY = value}
})// 触发动画
spring.endValue = 1.0 // 目标值
2. 关键点总结
- 优点:
- 自然流畅的物理动画效果。
- 支持自定义弹簧刚度、阻尼系数。
- 缺点:
- 需手动处理属性更新逻辑。
- 文档较少,调试成本高。
- 适用场景:弹性按钮、动态图标、物理模拟效果。
五、综合对比与选型指南
库名称 | 核心优势 | 适用场景 | 学习成本 | 性能影响 |
---|---|---|---|---|
Lottie | 复杂矢量动画支持 | 启动页、动态插画 | 低 | 中 |
MotionLayout | 布局过渡动画 | 页面转场、交互式布局 | 高 | 低 |
AndroidViewAnimations | 快速实现预定义动画 | 按钮反馈、简单动效 | 低 | 低 |
Rebound | 物理弹簧效果 | 弹性控件、物理模拟 | 中 | 中 |
六、总结
- Lottie 是设计师与开发者协作的首选工具,适合需要复杂矢量动画的场景。
- MotionLayout 在布局过渡动画中表现卓越,但需投入时间学习 XML 配置。
- AndroidViewAnimations 和 YoYo 适合快速实现简单动效,提升开发效率。
- Rebound 在需要物理交互的场景下不可替代,但需手动控制动画细节。
根据项目需求选择合适的动画库,既能提升用户体验,又能避免过度设计。
相关文章:
掌握 MotionLayout:交互动画开发
前言 在 Android 开发中,系统自带的属性动画(如 ObjectAnimator 和 ValueAnimator)虽然功能强大,但在复杂动画场景下,第三方动画库能提供更高效的开发体验和更丰富的效果。本文将深入解析 Lottie、MotionLayout、Andr…...

SpringBoot中缓存@Cacheable出错
SpringBoot中使用Cacheable: 错误代码: Cacheable(value "FrontAdvertiseVOList", keyGenerator "cacheKey") Override public List<FrontAdvertiseVO> getFrontAdvertiseVOList(Integer count) {return this.list(Wrappers.<Adve…...

iOS UIActivityViewController 组头处理
0x00 情形一 - (void)shareAction1 {// 当前 View 转成图片UIImage *image [self snapshotImage:self.view];NSArray *activityItems [image];UIActivityViewController *activityVC [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationAc…...
分布式电源接入配电网的自适应电流保护系统设计与实现
分布式电源接入配电网的自适应电流保护系统设计与实现 一、引言 随着可再生能源的快速发展,分布式电源(Distributed Generation, DG)大规模接入配电网,传统保护系统面临以下挑战: 潮流方向改变导致保护误动/拒动故障电流水平波动影响保护灵敏度多类型故障(单相/两相/三…...
鸿蒙版Taro 搭建开发环境
鸿蒙版Taro 搭建开发环境 一、配置鸿蒙环境 下载安装 DevEco 建议使用最新版本的 IDE,当前为 5.0.5Release 版本。 二、创建鸿蒙项目 打开 DevEco,点击右上角的 Create Project,在 Application 处选择 Empty Ability,点击 Ne…...
论对生产力决定生产关系的批判:突破决定论的桎梏
笔言: 在学生时代认为"生产力决定生产关系"很有道理,但是进入社会参与市场竞争时候,才发现这种想法太天真了,当生产力一只赔钱时候谁也不会感兴趣;当生产力产生利润,比如1%30%,100%,3…...
ESOP交易系统搭建全景指南:从合规基石到价值跃迁
第一章 重新定义ESOP:合规性与流动性的平衡艺术 1.1 ESOP的本质演进 传统认知误区:员工持股计划股权分配工具 现代定义: ESOP是企业资本运作的中枢神经系统,贯穿“激励授予→行权管理→减持流通→市值协同”全链条,需…...
GICv3电源管理
在符合GICv3体系结构的实现中,CPU接口和PE必须位于相同的电源域,但这不必与关联的Redistributor所在的电源域相同。 这意味着可能会出现PE及其CPU interface断电,而Redistributor、Distributor和its上电的情况。在这种情况下,GIC架…...

《TCP/IP 详解 卷1:协议》第3章:链路层
以太网和IEEE802局域网/城域网标准 IEEE802局域网/城域网标准 IEEE 802 是一组由 IEEE(电气与电子工程师协会)定义的局域网和城域网通信标准系列,涵盖了从物理层到链路层的多个网络技术。其中: IEEE 802.3 定义的是传统的以太网…...
centos 9/ubuntu 一次性的定时关机
方法一 # 15 表示15分钟以后自动关机 sudo shutdown -h 15方法二: sudo dnf install at -y # 晚上十点半关机 echo "shutdown -h now" | at 22:30 # 检查是否设置成功命令 atq [rootdemo-192 ~]# atq 1 Wed Jun 4 11:12:00 2025 a root # 取消定时计划…...

Elasticsearch从安装到实战、kibana安装以及自定义IK分词器/集成整合SpringBoot详细的教程(二)
package com.test.xulk.es.entity.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.test.xulk.es.entity.Hotel;public interface HotelMapper extends BaseMapper<Hotel> { }集成Springboot 项目里面 官方地址: Elasticsearch …...
Java自动类型转换的妙用
Java中的自动类型转换(也称为隐式类型转换)是指在不需要显式指定转换的情况下,Java编译器自动将一种数据类型转换为另一种数据类型。这种特性在编程中有许多妙用,以下是一些常见的应用场景和优点: 1. 简化代码 自动类…...

数据库管理-第333期 Oracle 23ai:RAC打补丁完全不用停机(20250604)
数据库管理333期 2025-06-04 数据库管理-第333期 Oracle 23ai:RAC打补丁完全不用停机(20250604)1 概念2 要求3 操作流程4 转移失败处理总结 数据库管理-第333期 Oracle 23ai:RAC打补丁完全不用停机(20250604࿰…...

【DAY39】图像数据与显存
内容来自浙大疏锦行python打卡训练营 浙大疏锦行 知识点: 图像数据的格式:灰度和彩色数据模型的定义显存占用的4种地方 模型参数梯度参数优化器参数数据批量所占显存神经元输出中间状态 batchisize和训练的关系 作业:今日代码较少࿰…...

AI代码库问答引擎Folda-Scan
简介 什么是 Folda-Scan ? Folda-Scan 是一款革命性的智能项目问答工具, 完全在浏览器中本地运行 。它使用高级语义矢量化将您的代码库转变为对话伙伴,使代码理解和 AI 协作变得前所未有的简单和安全。其采用尖端的 Web 技术和 AI 算法构建&…...

Kafka深度技术解析:架构、原理与最佳实践
一、 消息队列的本质价值与核心特性 1.1 分布式系统的“解耦器” 异步通信模型 代码列表 graph LRA[生产者] -->|异步推送| B[(消息队列)]B -->|按需拉取| C[消费者1]B -->|按需拉取| D[消费者2] 生产者发送后立即返回,消费者以自己的节奏处理消息。典…...

基于cnn的通用图像分类项目
背景 项目上需要做一个图像分类的工程。本人希望这么一个工程可以帮助学习ai的新同学快速把代码跑起来,快速将自己的数据集投入到实战中! 代码仓库地址:imageClassifier: 图片分类器 数据处理 自己准备的分类图像,按照文件夹分…...
Kotlin-协程
文章目录 什么是协程协程的好处协程的挂起和恢复协程原理 什么是协程 协程是一种用户态的轻量级程序组件,其核心特点是通过协作式调度实现单线程内的伪并发。 协程的好处 传统的线程切换通过回调,Handler各种调度,繁琐,代码不清…...
pycharm 左右箭头 最近编辑
目录 经典界面: 快捷键 经典界面: 如果你使用的是新 UI(新版 PyCharm 默认启用的),导航按钮可能被精简了,你可以: File Settings(齿轮图标)→ UI Appearance 或 New …...

Linux环境管道通信介绍
目录 前言 一、通信的本质 二、匿名管道 1.通信资源——文件缓冲区 2.为什么叫匿名管道? 编辑 3.匿名管道的创建过程 4.pipe函数 小结 5.一些问题 1)匿名管道为什么要求父子进程将原本的读/写权限只保留一个 2)为什么一开始父进程要以读/写…...

DIC技术助力金属管材全场应变测量:高效解决方案
在石油管道、汽车排气系统、航空航天液压管路等工业场景中,金属管作为关键承力部件,其拉伸性能(如弹性极限、颈缩行为、断裂韧性)直接影响结构安全性和使用寿命。 实际应用中,选用合适的管材非常重要,通过…...
python基础day04
1.两大编程思想的异同点: 面向过程面向对象区别事物比较简单,可以用线性的思维去解决事物比较复杂,使用简单的线性思维无法解决共同点面向过程和面向对象都是解决实际问题的一种思维方式二者相辅相成,并不是对立的解决复杂问题,通…...

嵌入式学习--江协stm32day1
失踪人口回归了,stm32的学习比起51要慢一些,因为涉及插线,可能存在漏插,不牢固等问题。 相对于51直接对寄存器的设置,stm32因为是32位修改起来比较麻烦,江协课程是基于标准库的,是对封装函数进…...

湖北理元理律师事务所:债务化解中的心理重建与法律护航
专业法律顾问视角 一、债务危机的双重属性:法律问题与心理困境 在对173名债务人的调研中发现: 68%存在焦虑引发的决策障碍(如不敢接听银行电话) 42%因羞耻感隐瞒债务导致雪球效应 湖北理元理律师事务所创新采用法律-心理双轨…...
constexpr 是 C++11 引入的关键字
constexpr 是 C11 引入的关键字,用于在编译期进行常量表达式计算,从而提高程序性能和安全性。以下是其核心作用和用法: 一.作用 1编译期 计算 constexpr 变量或函数的值在编译时确定,避免运行时计算开销。例如,数组大…...

【更新中】(文档+代码)基于推荐算法和Springboot+Vue的购物商城
概要设计 本节规划和定义了Woodnet桌游电商平台的软件概要设计说明书,描述了软件的总体设计、接口设计、运行设计、系统数据库结构设计以及系统出错处理设计,从整体上说明了系统设计的结构层次、处理流程、系统用例等。 本系统是一个独立的系统&#x…...

六种高阶微分方程的特解(原创:daode3056)
高阶微分方程的通解是指包含所有可能解的解的表达式。对于一个 n 阶微分方程,其通解通常包含 n 个任意常数。这些任意常数可以通过初始条件或边界条件来确定。高阶微分方程的特解是指在通解中,特定地选择了一组常数,使得解满足给定的初始条件…...

【C++11(上)】—— 我与C++的不解之缘(三十)
一、C11 这里简单了解一下C发展好吧: C11是C的第二个大版本,也是自C98以来最重要的一个版本。 它引入了大量的更改,它曾被人们称为C0x,因为它被期待在2010年之前发布;但在2011年8月12日才被采纳。 C03到C11花了8年时间…...

【多线程初阶】wait() notify()
文章目录 协调多个线程间的执行顺序join 和 wait 区别sleep 和 wait 区别 wait()方法线程饿死调用 wait()唤醒 wait() notify()方法wait() 和 notify() 需对同一对象使用确保先 wait ,后 notify多个线程在同一对象上wait notify随机唤醒一个wait notifyAll()方法应用 wait() 和…...

安全-JAVA开发-第二天
Web资源访问的流程 由此可见 客户访问JAVA开发的应用时 会先通过 监听器(Listener)和 过滤器(Filter) 今天简单的了解下这两个模块的开发过程 监听器(Listener) 主要是监听 我们触发了什么行为 并进行反应…...