移动应用的动画使它们变得生动而灵敏,引导用户的注意力并改善界面的感知。本文将探讨 iOS 和 Android 中的主要动画类型:Property Animation、View Animation、UIKit Dynamics、Core Animation、Lottie、Rive、Spring Animation、Hero Animation 和 Shared Element Transition。该材料将帮助初级开发人员了解针对特定任务应选择哪些工具和库。更多详情 — 请参阅官方 Android Animations 文档。
要点
Android 提供两种主要的动画系统:View Animation(旧版)和 Property Animation(现代)。View Animation(或 Tween Animation)仅对视觉表示进行操作 — 它更改 View 的显示,但不更改其实际属性(例如,点击坐标保持不变)。Property Animation 在 Android 3.0 中引入,通过 Animator(ValueAnimator、ObjectAnimator 或 AnimatorSet)更改对象的真实属性。
ObjectAnimator 是最流行的 Property Animation 类。它在指定时间内使用给定的 Interpolator 对对象的特定属性(例如 translationX、alpha、scaleY)进行动画处理。
ObjectAnimator.ofFloat(myView, "translationX", 0f, 300f).apply {
duration = 500
interpolator = FastOutSlowInInterpolator()
startDelay = 200
}.start()
ValueAnimator 不绑定到特定对象 — 它生成可用于任何属性或自定义逻辑的值。
View Animation 在 XML 文件 res/anim/ 中描述。支持四种类型:scale、translate、rotate、alpha。缺点是动画不会更改 View 的实际参数。对于简单的效果(闪烁、旋转),View Animation 仍然适用,但对于新项目,建议使用 Property Animation。
Jetpack Compose 提供现代动画 API:animateAsState、Animatable、AnimatedVisibility 和 AnimatedContent。Compose 中的动画是响应式的:当状态改变时,动画会自动启动。
var expanded = remember { mutableStateOf(false) }
val size = animateAsState(
if (expanded) 200f else 50f
)
Box(
modifier = Modifier
.size(size.value, size.value)
.clickable { expanded = !expanded }
.background(Color.Blue)
)
iOS 提供基于 Core Animation 的强大动画堆栈 — 一个与 CALayer 一起使用的低级框架。UIKit 构建在 Core Animation 之上,提供了方便的 UIView.animate 和 UIViewPropertyAnimator 方法。
UIView.animate 是在 iOS 中进行动画的最简单方式。允许对 frame、alpha、transform、backgroundColor 和其他 UIView 属性进行动画处理。
UIView.animate(
withDuration: 0.5,
delay: 0.2,
usingSpringWithDamping: 0.6,
initialSpringVelocity: 1.0,
options: [.curveEaseInOut]
) {
myView.frame.origin.x += 300
myView.alpha = 0.5
}
UIKit Dynamics — 一个用于物理动画的框架:重力、碰撞、弹簧、吸引力。允许在不手动计算物理的情况下创建逼真的对象行为。用于自定义过渡、动画菜单和游戏元素。
Core Animation(CAAnimation、CABasicAnimation、CAKeyframeAnimation)— 用于 CALayer 动画的低级 API。支持 3D 变换、路径动画(关键帧)、遮罩和合成。SwiftUI 通过 animation 和 withAnimation 修饰符在底层使用 Core Animation。
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.fromValue = 0
animation.toValue = CGFloat.pi * 2
animation.duration = 1.0
animation.repeatCount = .infinity
myLayer.add(animation, forKey: "rotation")
对于大多数 iOS 项目,使用 SwiftUI 及其内置动画。例如,withAnimation 将状态更改包装在动画上下文中。
复杂的动画(角色、过渡、加载器)很难用代码实现。Lottie 和 Rive 通过允许设计人员在可视化编辑器中创建动画并允许开发人员将其作为现成组件嵌入到应用程序中来解决此问题。
Lottie — 来自 Airbnb(现为 LottieFiles)的一个库,用于渲染从 Adobe After Effects 导出为 JSON 格式的动画。支持 Android、iOS、Flutter、React Native 和 Web。Lottie 动画是矢量动画,可缩放而不会丢失质量,并且可以通过编程方式自定义(速度、进度、颜色)。
// Android import com.airbnb.lottie.LottieAnimationView val lottieView = findViewById<LottieAnimationView>(R.id.lottieView) lottieView.setAnimation(R.raw.loading_animation) lottieView.playAnimation()
Rive(前身为 2Dimensions)— 一种更高级的矢量动画工具。与 Lottie 不同,Rive 支持交互式动画:状态、触发器、过渡。动画在 Rive Editor 中创建,并通过状态机在应用程序中控制。Rive 适用于游戏界面、动画图标和具有反馈的复杂过渡。
在 IT Sectr,我们使用 Lottie 进行装饰性动画(加载器、成功操作、空状态),使用 Rive 进行引导屏幕的交互式元素。与使用 UIKit 或 Canvas 手动实现相比,这可将动画开发时间减少 60%。
Shared Element Transition — 一种动画,其中元素(图像、文本、卡片)在屏幕之间过渡时平滑移动和变换。这创造了连续性的错觉:用户不是"进入"新屏幕,而是"陷入"元素中。
在 Android 中,过渡通过 ActivityOptionsCompat 和 transitionName 属性实现。FragmentTransaction 支持 addSharedElement 用于 Activity 内的过渡。Compose 使用 SharedTransitionLayout 和 SharedContentState。
iOS 没有内置的 Hero Transition,但 Hero 库(由 Luke Zhao 开发)在 UIKit 上实现了此模式。只需为两个屏幕上的元素分配一个 id — Hero 将自动创建一个平滑的过渡。在 SwiftUI 中,过渡动画通过 NavigationStack 和 matchedGeometryEffect 内置。
Flutter 有一个内置的 Hero 小部件,带有 tag 参数。当两个页面包含具有相同 tag 的 Hero 时,Flutter 会自动动画处理它们之间的过渡。这是在移动应用程序中实现复杂动画的最简单方法之一。
Hero( tag: 'profile_avatar', child: CircleAvatar( backgroundImage: AssetImage('avatar.jpg'), radius: 50, ), )
为了使动画看起来自然,使用了速度曲线 — Android 中的 Interpolator 和 iOS 中的 Easing。它们决定了动画速度从开始到结束的变化方式。
Android 支持多种内置插值器:LinearInterpolator(均匀)、AccelerateDecelerateInterpolator(慢-快-慢)、FastOutSlowInInterpolator(Material Design)、OvershootInterpolator(带过冲)和 BounceInterpolator(带弹跳)。可以通过 XML 或 TimeInterpolator 类创建自定义插值器。
| Interpolator | 行为 | 使用 |
|---|---|---|
| LinearInterpolator | 恒定速度 | 加载指示器、无限旋转 |
| FastOutSlowInInterpolator | 快速开始,平滑结束 | Material Design、卡片出现 |
| OvershootInterpolator | 超过目标并返回 | 强调元素、按钮 |
| BounceInterpolator | 结束时弹跳 | 列表、下拉刷新 |
Spring Animation(弹簧动画)使用阻尼(damping)和刚度(stiffness)参数对弹簧物理进行建模。阻尼 0 — 无限振荡,1 — 无振荡。刚度决定返回速度。Spring Animation 在 iOS(带有 UISpringTimingParameters 的 UIViewPropertyAnimator)、Android(physics2 中的 SpringAnimation)和 SwiftUI(spring())中可用。
Android 中的 Spring Animation 文档包含详细的配置示例。
Timeline(时间线)— 一种将动画随时间分割成帧的方法。用于 AnimationSet 或组动画不够灵活的复杂序列。Android 支持 AnimatorSet,iOS — CAAnimationGroup,Flutter — AnimationController 中的 Interval。
Часто задаваемые вопросы
View Animation(Android)仅更改 View 的视觉显示,而不更改实际属性(点击位置不变)。Property Animation 更改对象的实际属性,提供更灵活和可预测的行为。对于新项目,请始终使用 Property Animation。
Hero Animation 是一种动画,其中元素在屏幕之间过渡时平滑移动和变换,产生连续性的错觉。通过 Hero(Flutter)、SharedElementTransition(Android)或 matchedGeometryEffect(SwiftUI)实现。
Lottie 和 Rive 是用于在运行时渲染矢量动画的库。设计师在 After Effects(Lottie)或 Rive Editor 中创建动画,导出为 JSON,开发人员无需手动编写动画代码即可嵌入。
Spring Animation 对弹簧物理进行建模:动画具有自然的阻尼和"弹跳"。SwiftUI 和 Jetpack Compose 原生支持弹簧动画,使界面更加生动和灵敏。
选择取决于上下文:FastOutSlowIn — 用于元素出现,Overshoot — 用于强调,Linear — 用于加载指示器,Bounce — 用于列表。Material Design 推荐标准曲线:standard easing、deceleration easing 和 acceleration easing。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。