一、属性动画简介
Android官方在Anrdoid 3.0以后又推出了一种新的动画即属性动画,既然前面的帧动画和补间动画能帮助我们实现大部分的Android动画效果,那么官方为什么还要推出这种新的属性动画呢?
原因如下:
- 补间动画功能比较单调,只有四种动画(透明度,旋转,倾斜和位移)
- 补间动画针对的对象只是UI控件
- 补间动画只是改变View的显示效果,不会去改变View的属性
我们了解了下面6个类的基本用法,就基本彻底掌握了属性动画:
- ObjectAnimator 对象动画
- ValueAnimator 值动画
- PropertyValueHolder 用于同时执行多个动画
- TypeEvaluator 估值器
- AnimatorSet 动画集合
- Interpolator 差值器
- ViewPropertyAnimator 面向对象的属性动画操作方式
二、ValueAnimator简单使用
值动画通过控制值的变化,之后 手动赋值给对象的属性,从而实现动画。
1、使用流程
(1)调用ValueAnimator的ofInt(),ofFloat()或ofObject()静态方法创建ValueAnimator实例;
(2)调用实例的setXxx方法设置动画持续时间,插值方式,重复次数等;
(3)调用实例的addUpdateListener添加AnimatorUpdateListener监听器,在该监听器中 可以获得ValueAnimator计算出来的值,你可以值应用到指定对象上;
(4)调用实例的start()方法开启动画! 另外我们可以看到ofInt和ofFloat都有个这样的参数:float/int... values代表可以多个值!
2、核心方法
ValueAnimator ofFloat(float... values) -- 浮点型数值
ValueAnimator ofInt(int... values) -- 整型数值
ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) -- 自定义对象类型
3、使用
(1)5s完成透明度动画
final ImageView imageView = findViewById(R.id.imageView);
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(5000);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (float) animation.getAnimatedValue();
Log.d("MainActivity", "cuurent value is " + currentValue);
imageView.setAlpha(currentValue);
}
});
anim.start();
(2)2s设置View宽度
Button mButton = (Button) findViewById(R.id.button1);
ValueAnimator valueAnimator = ValueAnimator.ofInt(mButton.getLayoutParams().width, 500);
valueAnimator.setDuration(2000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
int currentValue = (Integer) animator.getAnimatedValue();
mButton.getLayoutParams().width = currentValue;
// 重绘,从而实现动画效果
mButton.requestLayout();
}
});
valueAnimator.start();
三、ObjectAnimator简单使用
ObjectAnimator
类是属性动画中非常重要的一个类,可以通过该类对View
不仅可以实现一些基本的移、旋转、缩放和透明度四种基本变换动画,还能实现一些其他属性值的变换动画。实现方式既可以通过Java代码,也可以通过xml方式来实现。
1、简介
首先我们先来看一下ObjectAnimator 类最基本的方法:
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
ObjectAnimator anim = new ObjectAnimator(target, propertyName);
anim.setFloatValues(values);
return anim;
}
方法中第一个参数Object target 的作用对象通常是View,也就是Android中的控件或布局。
方法中第二个参数String propertyName 通常是需要执行动画的属性,具体值如下表所示:
属性 | 含义 |
---|---|
rotation | 以屏幕方向为轴的旋转度数 |
alpha | 透明度 |
translationX / translationY | X/Y方向的位移 |
scaleX /scaleY | X/Y方向的缩放倍数 |
rotationX / rotationY | 以X/Y轴为轴的旋转度数 |
方法中第三个参数 float... values
表示属性的变换范围,该参数可以传多个值。
2、使用:
ImageView imageView = findViewById(R.id.imageView);
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f, 1f);
animator.setDuration(5000);
animator.start();
该动画效果表示控件ImageView 的透明度在5s内由1变换到0,再由0变回 1。
3、其他参数的使用
ImageView imageView = findViewById(R.id.imageView);
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f, 1f);
animator.setDuration(2000);
//动画延迟500ms执行
animator.setStartDelay(500);
//执行重复次数 +1
animator.setRepeatCount(3);
// 设置动画重复播放模式 RESTART -执行完一遍后重新执行
// REVERSE -执行完一遍后 从末位置往前执行
animator.setRepeatMode(ValueAnimator.RESTART);
//监听值变换
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i("MainActivity","value:" +animation.getAnimatedValue());
}
});
animator.start();
四、PropertyValueHolder
PropertyValueHolder 可以让前面的一些动画同时执行
ImageView imageView = findViewById(R.id.imageView);
PropertyValuesHolder alphaProper = PropertyValuesHolder.ofFloat("alpha", 0.5f, 1f);
PropertyValuesHolder scaleXProper = PropertyValuesHolder.ofFloat("scaleX", 0f, 1f);
PropertyValuesHolder scaleYProper = PropertyValuesHolder.ofFloat("scaleY", 0f, 1f);
PropertyValuesHolder translationXProper = PropertyValuesHolder.ofFloat("translationX", -100, 100);
PropertyValuesHolder translationYProper = PropertyValuesHolder.ofFloat("translationY", -100, 100);
PropertyValuesHolder rotationProper = PropertyValuesHolder.ofFloat("rotation", 0, 360);
ValueAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageView, alphaProper,
scaleXProper, scaleYProper,translationXProper,translationYProper,rotationProper);
animator.setDuration(5000);
animator.start();
五、动画组合(AnimatorSet)
前面的 PropertyValueHolder
类能实现将多个动画同时执行,AnimatorSet
类不仅能让多个动画同时执行,还能让多个动画按一定的顺序执行,同时也能穿插多个动画同时执行。
主要的方法如下:
- after(Animator anim) 将现有动画插入到传入的动画之后执行
- after(long delay) 将现有动画延迟指定毫秒后执行
- before(Animator anim) 将现有动画插入到传入的动画之前执行
- with(Animator anim) 将现有动画和传入的动画同时执行
示例:
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();
六、监听动画
ObjectAnimator animator = ObjectAnimator.ofFloat(center_text, "alpha", 1f, 0f, 1f);
animator.setDuration(3000);
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animator.start();
七、差值器
前面的动画属性的变换都是均匀变换,可以通过差值器(Interpolator)来控制值变化的速率
ImageView imageView = findViewById(R.id.imageView);
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 0f, 1f);
animator.setDuration(5000);
//加速查值器,参数越大,速度越来越快
animator.setInterpolator(new AccelerateInterpolator(5));
animator.start();
动画类型 | 含义 |
---|---|
AccelerateInterpolator | 加速查值器,参数越大,速度越来越快 |
DecelerateInterpolator | 减速差值起,和加速查值器相反 |
AccelerateDecelerateInterpolator | 先加速后减速 |
AnticipateInterpolator | 先后退在加速前进 |
AnticipateOvershootInterpolator | 以X/Y轴为轴的旋转度数 |
BounceInterpolator | 弹球效果插值 |
CycleInterpolator | 周期运动插值 |
LinearInterpolator | 匀速插值 |
OvershootInterpolator | 先快速完成动画,再回到结束样式 |
八、估值器
后续补充
九、ViewPropertyAnimator
1、简介
Android提供了一组属性动画API,可以方便的创建属性动画。属性动画的使用方法按照封装程度从低到高(自由度从高到低)依次为 ValueAnimator
、ObjectAnimator
、ViewPropertyAnimator
三种,其中ValueAnimator
是核心,ObjectAnimator
继承于ValueAnimator
,ViewPropertyAnimator
内部采用ValueAnimator
实现动画。
ViewPropertyAnimator
内部使用单个 ValueAnimator
对象为 View 的多个属性并行添加动画效果。它的行为方式与ObjectAnimator
非常相似,它会修改视图属性的实际值,但在同时为多个属性添加动画效果时,更为高效。使用 ViewPropertyAnimator
的代码也更简洁,也更易读。
2、常用API
常用方法 | 含义 |
---|---|
translationX(float value) | 向X轴的移动value的距离 |
translationY(float value) | 向Y轴的移动value的距离 |
x(float value)、y(float value) | x(valueX)、y(valueY):将目标View移动到(valueX,valueY)的坐标点上 |
alpha() | 设置View的透明度 |
rotation() | 旋转View |
scaleX(float value)、scaleY(float value) | 设置View的放缩,value是倍数,如设置scaleX(2f)是View在X轴方向放大2倍,scaleY同理 |
setDuration(long duration) | 设置动画持续时间 |
setStartDelay(long startDelay) | 动画开始之前的延迟时间 |
setListener(Animator.AnimatorListener listener) | 动画监听 |
setInterpolator(TimeInterpolator interpolator) | 时间插值器,用来修饰动画效果 |
setUpdateListener(ValueAnimator.AnimatorUpdateListener listener) | 在API 19或以上使用 动画更新回调 |
withStartAction(Runnable runnable) | 动画开始时设置的行为 |
withEndAction(Runnable runnable) | 动画结束时设置的行为 |
xBy(float value) | 在当前值的基础上,修改view 的X坐标 |
yBy(float value) | 在当前值的基础上,修改View的Y的坐标 |
zBy(float value) | 在当前值的基础上,修改View的Z的坐标 |
withLayer() | 开启硬件加速,动画结束自动关闭 |
cancel() | 取消动画 |
3、使用示例:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var button: Button = findViewById(R.id.bt)
button.animate()
.translationX(150f) //x轴向右平移
.translationY(100f) //y轴向下平移
.scaleX(1.5f) //x方向放大1.5倍
.scaleY(2f) //y方向放大2倍
.setStartDelay(2000) //延时2000秒,才开始执行动画
.setInterpolator(DecelerateInterpolator()) //设置减速插值器
.setDuration(800) //动画执行时长800毫秒
.setListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator?) {
}
override fun onAnimationEnd(animation: Animator?) {
}
override fun onAnimationCancel(animation: Animator?) {
}
override fun onAnimationRepeat(animation: Animator?) {
}
})
.start() //开始执行
}
}
4、小结
整个
ViewPropertyAnimator
的功能都是建立在View类新增的animate()
方法之上的,这个方法会创建并返回一个ViewPropertyAnimator
的实例,之后的调用的所有方法,设置的所有属性都是通过这个实例完成的。大家注意到,在使用
ViewPropertyAnimator
时,我们自始至终没有调用过start()
方法,这是因为新的接口中使用了隐式启动动画的功能,只要我们将动画定义完成之后,动画就会自动启动。并且这个机制对于组合动画也同样有效,只要我们不断地连缀新的方法,那么动画就不会立刻执行,等到所有在ViewPropertyAnimator
上设置的方法都执行完毕后,动画就会自动启动。当然如果不想使用这一默认机制的话,我们也可以显式地调用start()
方法来启动动画。ViewPropertyAnimator
的所有接口都是使用连缀的语法来设计的,每个方法的返回值都是它自身的实例,因此调用完一个方法之后可以直接连缀调用它的另一个方法,这样把所有的功能都串接起来,我们甚至可以仅通过一行代码就完成任意复杂度的动画功能。
参考链接:
https://blog.csdn.net/weixin_53431933/article/details/126044835
https://blog.csdn.net/huweiliyi/article/details/105671079
https://blog.csdn.net/zhaoyanjun6/article/details/111650621