Android动画效果 #

一、动画概述 #

Android提供了多种动画实现方式,可以创建丰富的视觉效果,提升用户体验。

1.1 动画分类 #

类型 说明 特点
补间动画(Tween Animation) View动画 只改变显示效果,不改变实际位置
帧动画(Frame Animation) 逐帧播放 类似GIF,播放一系列图片
属性动画(Property Animation) 属性变化 真正改变View的属性值

1.2 动画应用场景 #

  • 页面切换动画
  • 控件交互动画
  • 加载动画
  • 引导动画

二、补间动画 #

2.1 动画类型 #

动画 类名 说明
透明度 AlphaAnimation 渐变透明度
缩放 ScaleAnimation 缩放大小
平移 TranslateAnimation 移动位置
旋转 RotateAnimation 旋转角度

2.2 XML定义动画 #

xml
<!-- res/anim/scale.xml -->
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="1.0"
    android:toXScale="2.0"
    android:fromYScale="1.0"
    android:toYScale="2.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="1000"
    android:fillAfter="true"
    android:repeatCount="infinite"
    android:repeatMode="reverse" />
kotlin
val animation = AnimationUtils.loadAnimation(this, R.anim.scale)
view.startAnimation(animation)

2.3 代码创建动画 #

kotlin
// 透明度动画
val alphaAnimation = AlphaAnimation(1f, 0f).apply {
    duration = 1000
    fillAfter = true
}
view.startAnimation(alphaAnimation)

// 缩放动画
val scaleAnimation = ScaleAnimation(
    1f, 2f,  // X轴从1到2
    1f, 2f,  // Y轴从1到2
    Animation.RELATIVE_TO_SELF, 0.5f,  // X轴中心点
    Animation.RELATIVE_TO_SELF, 0.5f   // Y轴中心点
).apply {
    duration = 1000
}
view.startAnimation(scaleAnimation)

// 平移动画
val translateAnimation = TranslateAnimation(
    0f, 200f,  // X轴从0到200
    0f, 0f     // Y轴不变
).apply {
    duration = 1000
}
view.startAnimation(translateAnimation)

// 旋转动画
val rotateAnimation = RotateAnimation(
    0f, 360f,  // 角度从0到360
    Animation.RELATIVE_TO_SELF, 0.5f,
    Animation.RELATIVE_TO_SELF, 0.5f
).apply {
    duration = 1000
}
view.startAnimation(rotateAnimation)

2.4 动画集合 #

xml
<!-- res/anim/set.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.0"
        android:duration="1000" />
    
    <scale
        android:fromXScale="1.0"
        android:toXScale="0.5"
        android:fromYScale="1.0"
        android:toYScale="0.5"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="1000" />
</set>
kotlin
val animationSet = AnimationSet(true).apply {
    addAnimation(AlphaAnimation(1f, 0f))
    addAnimation(ScaleAnimation(1f, 0.5f, 1f, 0.5f, 
        Animation.RELATIVE_TO_SELF, 0.5f, 
        Animation.RELATIVE_TO_SELF, 0.5f))
    duration = 1000
}
view.startAnimation(animationSet)

2.5 动画监听 #

kotlin
animation.setAnimationListener(object : Animation.AnimationListener {
    override fun onAnimationStart(animation: Animation?) {
        // 动画开始
    }
    
    override fun onAnimationEnd(animation: Animation?) {
        // 动画结束
    }
    
    override fun onAnimationRepeat(animation: Animation?) {
        // 动画重复
    }
})

三、帧动画 #

3.1 XML定义 #

xml
<!-- res/drawable/animation_list.xml -->
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    
    <item android:drawable="@drawable/frame1" android:duration="100" />
    <item android:drawable="@drawable/frame2" android:duration="100" />
    <item android:drawable="@drawable/frame3" android:duration="100" />
    <item android:drawable="@drawable/frame4" android:duration="100" />
    
</animation-list>

3.2 使用帧动画 #

xml
<ImageView
    android:id="@+id/imageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/animation_list" />
kotlin
val imageView = findViewById<ImageView>(R.id.imageView)
val animationDrawable = imageView.drawable as AnimationDrawable

// 开始动画
animationDrawable.start()

// 停止动画
animationDrawable.stop()

四、属性动画 #

4.1 ValueAnimator #

kotlin
val animator = ValueAnimator.ofFloat(0f, 1f).apply {
    duration = 1000
    
    addUpdateListener { animation ->
        val value = animation.animatedValue as Float
        // 使用value更新属性
        view.alpha = value
    }
    
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            // 动画结束
        }
    })
}

animator.start()

4.2 ObjectAnimator #

kotlin
// 透明度
val alphaAnimator = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f, 1f)
alphaAnimator.duration = 1000
alphaAnimator.start()

// 平移
val translateAnimator = ObjectAnimator.ofFloat(view, "translationX", 0f, 200f)
translateAnimator.duration = 1000
translateAnimator.start()

// 缩放
val scaleAnimator = ObjectAnimator.ofFloat(view, "scaleX", 1f, 2f)
scaleAnimator.duration = 1000
scaleAnimator.start()

// 旋转
val rotateAnimator = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f)
rotateAnimator.duration = 1000
rotateAnimator.start()

4.3 AnimatorSet #

kotlin
val animatorSet = AnimatorSet()

val scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 2f)
val scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 2f)
val alpha = ObjectAnimator.ofFloat(view, "alpha", 1f, 0.5f)

// 同时播放
animatorSet.playTogether(scaleX, scaleY, alpha)

// 顺序播放
animatorSet.playSequentially(scaleX, scaleY, alpha)

// 组合播放
animatorSet.play(scaleX).with(scaleY).before(alpha)

animatorSet.duration = 1000
animatorSet.start()

4.4 PropertyValuesHolder #

kotlin
val holderX = PropertyValuesHolder.ofFloat("scaleX", 1f, 2f)
val holderY = PropertyValuesHolder.ofFloat("scaleY", 1f, 2f)
val holderAlpha = PropertyValuesHolder.ofFloat("alpha", 1f, 0.5f)

val animator = ObjectAnimator.ofPropertyValuesHolder(view, holderX, holderY, holderAlpha)
animator.duration = 1000
animator.start()

4.5 Keyframe #

kotlin
val keyframe1 = Keyframe.ofFloat(0f, 0f)
val keyframe2 = Keyframe.ofFloat(0.5f, 180f)
val keyframe3 = Keyframe.ofFloat(1f, 360f)

val holder = PropertyValuesHolder.ofKeyframe("rotation", keyframe1, keyframe2, keyframe3)
val animator = ObjectAnimator.ofPropertyValuesHolder(view, holder)
animator.duration = 1000
animator.start()

4.6 插值器 #

kotlin
// 加速插值器
animator.interpolator = AccelerateInterpolator()

// 减速插值器
animator.interpolator = DecelerateInterpolator()

// 加速减速插值器
animator.interpolator = AccelerateDecelerateInterpolator()

// 弹性插值器
animator.interpolator = BounceInterpolator()

// 超出插值器
animator.interpolator = OvershootInterpolator()

// 预测插值器
animator.interpolator = AnticipateInterpolator()

// 自定义插值器
animator.interpolator = TimeInterpolator { input ->
    // input: 0-1的进度值
    // 返回: 0-1的插值结果
    input * input
}

4.7 估值器 #

kotlin
// 自定义估值器
class PointEvaluator : TypeEvaluator<PointF> {
    override fun evaluate(fraction: Float, startValue: PointF, endValue: PointF): PointF {
        val x = startValue.x + fraction * (endValue.x - startValue.x)
        val y = startValue.y + fraction * (endValue.y - startValue.y)
        return PointF(x, y)
    }
}

val animator = ValueAnimator.ofObject(PointEvaluator(), PointF(0f, 0f), PointF(100f, 100f))
animator.addUpdateListener { animation ->
    val point = animation.animatedValue as PointF
    view.x = point.x
    view.y = point.y
}
animator.start()

五、ViewPropertyAnimator #

kotlin
// 简单动画
view.animate()
    .alpha(0.5f)
    .scaleX(2f)
    .scaleY(2f)
    .translationX(100f)
    .rotation(360f)
    .setDuration(1000)
    .setInterpolator(AccelerateDecelerateInterpolator())
    .withStartAction { 
        // 动画开始
    }
    .withEndAction { 
        // 动画结束
    }
    .start()

六、过渡动画 #

6.1 Activity过渡 #

kotlin
// 启动Activity
val intent = Intent(this, SecondActivity::class.java)
val options = ActivityOptions.makeSceneTransitionAnimation(
    this,
    view,
    "shared_element"
)
startActivity(intent, options.toBundle())

// 在第二个Activity中设置
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
window.sharedElementEnterTransition = ChangeBounds()

6.2 Fragment过渡 #

kotlin
val fragment = MyFragment()
fragment.enterTransition = Slide()
fragment.exitTransition = Fade()
fragment.sharedElementEnterTransition = ChangeBounds()

supportFragmentManager.beginTransaction()
    .addSharedElement(view, "shared_element")
    .replace(R.id.container, fragment)
    .commit()

七、总结 #

本章详细介绍了Android动画:

  1. 动画的分类和应用场景
  2. 补间动画的使用
  3. 帧动画的使用
  4. 属性动画的使用
  5. ViewPropertyAnimator简化动画
  6. 过渡动画

合理使用动画可以提升应用的用户体验,但要注意不要过度使用,以免影响性能。

最后更新:2026-03-26