解释:
- 作用对象:任意对象,甚至没对象也可以
- 作用方式:改变对象的属性
- 动画效果:按需自定义,不再局限于上述4种基本变换
核心类:
- ObjectAnimator 一个对象的一个属性动画 对属性进行改变。 (比如 View 的宽 高 位置等...)
- AnimatorSet 动画的集合 可以同步进行几个动画 或者 顺序执行几个动画。
- ValueAnimator 为ObjectAnimator 的父类,与ObjectAnimator 区别为改变属性需要对View 进行手动赋值,进行平滑的过度。
- TimeAnimator 时序监听回调工具。
1.ObjectAnimator
ObjectAnimator.ofFloat(View, "newWidth", 0, 40) 改变宽度
ObjectAnimator.ofFloat(View, "rotation", 15, 0) 改变角度
ObjectAnimator.ofFloat(View, "translationY", 0, -54) 平移Y
ObjectAnimator.ofFloat(View, "translationX", 0, -54) 平移X
// 透明度渐变
ObjectAnimator objectAlphaAnimator = ObjectAnimator.ofFloat(mCheckMarkAlphaIv,"alpha",1f,0.2f);
objectAlphaAnimator.setDuration(1000);
objectAlphaAnimator.start();
// 移动
ObjectAnimator objectTranslationXAnimator = ObjectAnimator.ofFloat(mCheckMarkTranslationXIv,"translationX",0f,1000f);
objectTranslationXAnimator.setDuration(1000);
objectTranslationXAnimator.setInterpolator(new AccelerateInterpolator());
objectTranslationXAnimator.start();
// 旋转
ObjectAnimator objectRotationAnimator = ObjectAnimator.ofFloat(mCheckMarkRotationIv,"rotation",360f,0f);
objectRotationAnimator.setDuration(1000);
objectRotationAnimator.start();
//宽度
ObjectAnimator objectWidthAnimator = ObjectAnimator.ofInt(mCheckMarkWidthIv,"viewWidth",0,600,400);
objectWidthAnimator.setDuration(1000);
objectWidthAnimator.start();
以此类推改变View 的属性进行动画,属性动画改变的是View 真正的属性,执行动画之后View的属性发生了实质性的改变。
2. 解决一些控件无属性的方法,不能改变属性的问题:
setViewWidth() 为新增的一个方法,想改变宽度只用改变viewWidth的属性即可
public class ChangeWidthImgeView extends ImageView {
public ChangeWidthImgeView(Context context) {
super(context);
}
public ChangeWidthImgeView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ChangeWidthImgeView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setViewWidth(int viewWidth){
getLayoutParams().width = viewWidth;
requestLayout();
}
}
动画效果
2.ValueAnimator
为ObjectAnimator 的父类,与ObjectAnimator 区别为改变属性需要对View 进行手动赋值,进行平滑的过度。
//1. 获取实例
//2. 在传入参数之间平滑过渡
//如下则230平滑过渡到0
ValueAnimator animator = ValueAnimator.ofInt(230,150,100,0);
//设置更新监听
//值 改变一次,该方法就执行一次
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//获取改变后的值
int currentValue = (int) animation.getAnimatedValue();
//改变后的值发赋值给对象的属性值,改变View的透明度
mFinger.setAlpha(currentValue);
//刷新视图
mFinger.requestLayout();
}
});
ValueAnimator yalueAnimator = ValueAnimator.ofInt(0,-50,-100,-150,-200,-250,-300,-350);
yalueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int currentValue = (int) animation.getAnimatedValue();
//改变后的值发赋值给对象的属性值,改变View的水平Y
mFinger.setTranslationY(currentValue);
mFinger.requestLayout();
}
});
//设置循环
animator.setRepeatCount(-1);
//设置循环
yalueAnimator.setRepeatCount(-1);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animator,yalueAnimator);
animatorSet.setDuration(3000);
animatorSet.start();
动画效果
如图所示可以设置更多的细节值,让动画执行执行起来可以有更多的细节调整和动画平滑的过渡的需求。
3.AnimatorSet (组合动画)
在AnimatorSet中给为我们提供了两个方法playSequentially和playTogether,
1.playSequentially表示所有动画依次播放
2.playTogether表示所有动画一起开始
playSequentially 顺序播放 方法有2个声明
public void playSequentially(Animator... items);
public void playSequentially(List<Animator> items)
2 playTogether 并行播放 方法有2个声明
public void playTogether(Animator... items);
public void playTogether(Collection<Animator> items);
setDuration(long duration) // 设置动画时间
setInterpolator(TimeInterpolator interpolator) // 设置插值器
start() //开始动画
这2种使用的方式都是大同小异,一般使用这2种方法的第一个方法
代码实列 :
// 顺序播放组合动画
AnimatorSet allAnimator = new AnimatorSet();
allAnimator.playSequentially(oneAnimator,twoAnimator,threeAnimator);
allAnimator.start();
// 并行播放 组合动画+单独的动画
AnimatorSet allAnimator = new AnimatorSet();
allAnimator.playTogether(oneAnimator,ObjectAnimator);
// 设置时间
allAnimator.setDuration(1000);
// 设置一个插值器
allAnimator.setInterpolator(new AccelerateInterpolator());
// 开始动画
allAnimator.start();
组合属性动画实列 (几何碰撞)
观看上列动画进行动画的分解:
1. 左边正方形向右移动,中间小圆点和正方形同步执行,小圆点落下和正方形进行碰撞,并且正方形发生颜色改变和旋转动画。
2.小圆点碰撞之后向左移动并且改变颜色和形状完成之后向右移动碰撞中心正方形后消失。
3.中心小正方形在接受到左边橙色小正方形碰撞之后,向右移动然后向左移动碰撞中心红色大圆形,红色大圆形缩小。
分为3步去分解整个动画,便于逻辑清晰,更好的完成动画。
动画代码实列
// 移动
ObjectAnimator objectBack2TranslationXAnimator = ObjectAnimator.ofFloat(mLeftSquareIv,"translationX",0f,783f);
ObjectAnimator objectTranslationXAnimator = ObjectAnimator.ofFloat(mLeftSquareIv,"translationX",0f,845f);
ObjectAnimator objectBackTranslationXAnimator = ObjectAnimator.ofFloat(mLeftSquareIv,"translationX",845f,0f);
objectBackTranslationXAnimator.setDuration(300);
ObjectAnimator objectTranslationYAnimator = ObjectAnimator.ofFloat(mRightSquareIv,"translationY",0f,-60f,0f);
ObjectAnimator gardenBackTranslationXAnimator = ObjectAnimator.ofFloat(mRightSquareIv,"translationX",500f,0f);
gardenBackTranslationXAnimator.setDuration(300);
ObjectAnimator translationXAnimator = ObjectAnimator.ofFloat(mRightSquareIv,"translationX",0f,500f);
translationXAnimator.setDuration(300);
//变色
ObjectAnimator objectColorAnimator = ObjectAnimator.ofArgb(mLeftSquareIv,"backgroundColor",getResources().getColor(R.color.holo_orange_light),getResources().getColor(R.color.holo_purple));
ObjectAnimator objectGardenColorAnimator = ObjectAnimator.ofArgb(mRightSquareIv,"backgroundColor",getResources().getColor(R.color.connect_color),getResources().getColor(R.color.holo_orange_dark));
// 旋转
ObjectAnimator objectRotationAnimator = ObjectAnimator.ofFloat(mLeftSquareIv,"rotation",360f,180f,0f);
objectRotationAnimator.setInterpolator(new BounceInterpolator());
objectRotationAnimator.setDuration(200);
//小正方形消失
ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(mRightSquareIv,"scaleX",1f,0.0f);
ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(mRightSquareIv,"scaleY",1f,0.0f);
AnimatorSet scaleAnimatorSet = new AnimatorSet();
scaleAnimatorSet.playTogether(scaleXAnimator,scaleYAnimator);
scaleAnimatorSet.setDuration(200);
//大圆形缩小
ObjectAnimator scaleXAnimators = ObjectAnimator.ofFloat(mCentralParkIv,"scaleX",1f,0.25f);
ObjectAnimator scaleYAnimators = ObjectAnimator.ofFloat(mCentralParkIv,"scaleY",1f,0.25f);
AnimatorSet scaleAnimatorSets = new AnimatorSet();
scaleAnimatorSets.playTogether(scaleXAnimators,scaleYAnimators);
scaleAnimatorSets.setDuration(300);
// 第一个动画并行 正方形冲撞加中心小园跳起
AnimatorSet oneAnimator = new AnimatorSet();
oneAnimator.setDuration(1000);
oneAnimator.setInterpolator(new AccelerateInterpolator());
oneAnimator.playTogether(objectTranslationXAnimator,objectTranslationYAnimator);
//第二个动画并行 正方形变色 旋转, 小圆移动 变色 变正方形
AnimatorSet twoAnimator = new AnimatorSet();
twoAnimator.playTogether(objectColorAnimator,objectRotationAnimator,translationXAnimator,objectGardenColorAnimator);
// 动画顺序执行 左边正方形第二次位移,撞击完成 大圆缩小
AnimatorSet leftAnimator = new AnimatorSet();
leftAnimator.playSequentially(objectBack2TranslationXAnimator,scaleAnimatorSets);
// 右边小圆返回撞击中心正方形,然后消失
AnimatorSet rightAnimator = new AnimatorSet();
rightAnimator.playTogether(leftAnimator,scaleAnimatorSet);
//第三个动画顺序执行 右边小正方形返回
AnimatorSet threeAnimator = new AnimatorSet();
threeAnimator.playSequentially(gardenBackTranslationXAnimator,rightAnimator);
// 最终的AnimatorSet进行顺序执行
AnimatorSet allAnimator = new AnimatorSet();
allAnimator.playSequentially(oneAnimator,twoAnimator,threeAnimator);
allAnimator.start();