1,属性动画特点
-
更灵活的动画控制: 属性动画可以控制任何对象的任何属性,包括自定义对象和属性。这使得你可以在动画期间修改对象的各种属性,比如位置、大小、透明度等。
-
流畅性和自然性: 属性动画能够实现更加流畅和自然的动画效果。它通过修改属性值来实现动画,而不是像View动画那样只是简单地改变绘制位置,因此能够产生更加平滑和逼真的动画。
-
支持任意对象类型: 除了View对象,属性动画还可以作用于任意Java对象,只要该对象具有需要进行动画的属性,并且提供了setter和getter方法。
-
动画插值器和加速器: 属性动画支持使用插值器(Interpolator)和加速器(Accelerator)来控制动画的速度变化,从而实现不同的动画效果,比如匀速运动、先加速后减速等。
-
动画链和组合: 可以将多个动画组合成一个动画链或者同时播放多个动画,实现更加复杂的动画效果。
-
可监听动画状态: 可以为属性动画设置监听器,监听动画的各种状态变化,比如动画开始、结束、取消等。
-
XML和代码两种方式配置: 属性动画可以通过XML文件或者Java代码来配置和使用,灵活性更高。
2,属性动画用法
1.使用ObjectAnimator
进行基础属性操作(位置,大小,透明度等)
val view = findViewById<View>(R.id.my_view)
// 创建 ObjectAnimator 对象,对 View 的 alpha 属性进行动画
val animator = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f)
animator.duration = 1000 // 设置动画持续时间为1秒
进行自定义属性操作(例子:有一个自定义的 Circle
对象,可以对其半径进行动画操作)
data class Circle(var radius: Float)
val circle = Circle(0f)
// 创建 ObjectAnimator 对象,对 Circle 对象的 radius 属性进行动画
val animator = ObjectAnimator.ofFloat(circle, "radius", 0f, 100f)
animator.duration = 1000
animator.addUpdateListener { animation ->
// 监听动画过程中属性值的变化
val currentRadius = animation.animatedValue as Float
circle.radius = currentRadius
// 刷新 UI,更新绘制
invalidate()
}
2.使用ValueAnimator
解释:它可以在一定时间范围内逐步改变某个值,并在每一帧更新该值。与 ObjectAnimator
不同,ValueAnimator
并不直接操作目标对象的属性,而是通过监听器来获取动画过程中的当前值,并手动应用到目标对象上。
示例:改变画笔颜色
ValueAnimator animator = ValueAnimator.ofArgb(startColor, endColor);
animator.setDuration(1500);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int animatedValue = (int) animation.getAnimatedValue();
paint.setColor(animatedValue);
// 在这里进行重绘操作
}
});
animator.start();
3,其他用法
1,PropertyValueHolder 用于同时执行多个动画
PropertyValuesHolder
是属性动画框架中的一个重要类,它可以封装要同时操作的多个属性和对应的值。通过使用 PropertyValuesHolder
,可以实现同时对多个属性进行动画操作,从而创建更复杂的动画效果。与 ObjectAnimator
和 ValueAnimator
结合使用,可以实现丰富多样的属性动画效果。
示例:使 view
在1.5秒内同时进行平移和旋转动画。
PropertyValuesHolder translationX = PropertyValuesHolder.ofFloat("translationX", 0f, 200f);
PropertyValuesHolder translationY = PropertyValuesHolder.ofFloat("translationY", 0f, 200f);
PropertyValuesHolder rotation = PropertyValuesHolder.ofFloat("rotation", 0f, 360f);
ValueAnimator animator = ValueAnimator.ofPropertyValuesHolder(translationX, translationY, rotation);
animator.setDuration(1500);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float translationXValue = (float) animation.getAnimatedValue("translationX");
float translationYValue = (float) animation.getAnimatedValue("translationY");
float rotationValue = (float) animation.getAnimatedValue("rotation");
view.setTranslationX(translationXValue);
view.setTranslationY(translationYValue);
view.setRotation(rotationValue);
}
});
animator.start();
2,动画组合 AnimatorSet
前面的PropertyValueHolder
类能实现将多个动画同时执行,AnimatorSet
类不仅能让多个动画同时执行,还能让多个动画按一定的顺序执行,同时也能穿插多个动画同时执行
ImageView imageView = findViewById(R.id.imageView);
ObjectAnimator rotate = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
ObjectAnimator translationX = ObjectAnimator.ofFloat(imageView, "translationX", -100, 100f);
ObjectAnimator translationY = ObjectAnimator.ofFloat(imageView, "translationY", -100, 100f);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(imageView, "scaleX", 0, 1f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(imageView, "scaleY", 0, 1f);
ObjectAnimator alpha = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f, 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(rotate)
.with(alpha)
.after(scaleX)
.before(translationX)
.after(1000)
.before(translationY)
.with(scaleY);
animSet.setDuration(5000);
animSet.start();
4,其他内容
1.,差值器(Interpolator):
作用:
1,控制动画的变化速度: Interpolator 描述了动画在时间上的变化规律,决定了动画在不同时间点上的属性值应该处于何种状态。它决定了动画的加速度和减速度。
2,提供动画效果的定制: Interpolator 可以让您定义自己的动画效果,例如缓慢启动、加速和减速等。
基本类型:
Interpolator 类型 | 解释 |
线性插值器(LinearInterpolator) | 动画的速度始终保持恒定,直线运动 |
加速插值器(AccelerateInterpolator) | 动画逐渐加速,常用于动画的起始部分 |
减速插值器(DecelerateInterpolator) | 动画逐渐减速,常用于动画的结束部分 |
加速减速插值器(AccelerateDecelerateInterpolator) | 动画先加速再减速,常用于使动画效果更加自然 |
抛物线插值器(CycleInterpolator) | 动画在循环中重复播放,可以指定循环次数和循环类型 |
反弹插值器(BounceInterpolator) | 动画在结束时会有一个反弹效果,使得动画看起来更加生动。 |
弹簧插值器(SpringInterpolator) | 模拟弹簧的效果,常用于弹性动画。 |
路径插值器(PathInterpolator) | 可以根据自定义的路径来控制动画的变化速度,实现更加复杂的动画效果。 |
(除开上述几种,还可自定义类型)
示例:
ImageView imageView = findViewById(R.id.imageView);
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 0f, 1f);
animator.setDuration(5000);
//加速查值器,参数越大,速度越来越快
animator.setInterpolator(new AccelerateInterpolator(5));
animator.start();
2,估值器(TypeEvaluator)
解释:用于计算属性值在动画过程中的过渡值。在属性动画中,通过指定初始值和结束值,以及动画的持续时间和插值器,属性动画系统会根据这些参数计算出每一帧中属性值的过渡值。而估值器则负责根据这些过渡值来计算出最终的属性值。
实现自定义估值器示例:
public class ColorEvaluator implements TypeEvaluator<Integer> {
@Override
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
// 获取起始颜色的 ARGB 分量
int startAlpha = Color.alpha(startValue);
int startRed = Color.red(startValue);
int startGreen = Color.green(startValue);
int startBlue = Color.blue(startValue);
// 获取结束颜色的 ARGB 分量
int endAlpha = Color.alpha(endValue);
int endRed = Color.red(endValue);
int endGreen = Color.green(endValue);
int endBlue = Color.blue(endValue);
// 根据动画进度 fraction 计算过渡颜色的 ARGB 分量
int currentAlpha = (int) (startAlpha + (endAlpha - startAlpha) * fraction);
int currentRed = (int) (startRed + (endRed - startRed) * fraction);
int currentGreen = (int) (startGreen + (endGreen - startGreen) * fraction);
int currentBlue = (int) (startBlue + (endBlue - startBlue) * fraction);
// 组合 ARGB 分量并返回过渡颜色
return Color.argb(currentAlpha, currentRed, currentGreen, currentBlue);
}
}
使用自定义估值器:
ValueAnimator animator = ValueAnimator.ofObject(new ColorEvaluator(), startColor, endColor);