这篇文章只是对属性动画的一个简单的概括,下面所有的例子,都在这个Demo里,首先总结一下属性动画用到的东西
- ObjectAnimator
- ValueAnimator
- PropertyValueHolder
- TypeEvaluator
- Interpolator
首先看一下ObjectAnimator的简单使用
ObjectAnimator oa = ObjectAnimator.ofFloat(mIv, "translationX", 0f, 200f);
oa.setDuration(500);
oa.start();
效果是这样的
逗我?有什么特殊的吗?其实属性动画会改变view的 实际属性。比如:改变button的位置,平移后的状态还是可以被点击的,而传统2D动画只是 canvas绘制的,移动是用 Matrix变换View的位置,并没有改变view的实际属性。
ObjectAnimator还有一些其他的属性
oa.reverse();//与start()二选一,这个执行与start相反
oa.setRepeatCount(1);//重复次数
oa.setRepeatCount(ValueAnimator.INFINITE);//无限循环
oa.setStartDelay(1000);//设置延迟执行
//与重复动画配合使用
oa.setRepeatMode(ValueAnimator.RESTART);//重新开始
oa.setRepeatMode(ValueAnimator.REVERSE);//反转开始
//重写全部的监听
oa.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) {}//重复
});
//重写需要的
oa.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation){super.onAnimationEnd(animation);}
});
注释很明确就不多做演示。多个动画同是执行应该怎么实现呢,这里有很多实现的方式。先看第一种用ObjectAnimator来实现。
ObjectAnimator animator = ObjectAnimator.ofFloat(mIv, "translationX", 0f, 100f);
animator.setDuration(300);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 监听动画回调
//animation.getAnimatedFraction();//动画执行的百分比 0~1 //API 12+
float value = (float) animation.getAnimatedValue();//得到0f~100f当中的这个时间点对应的值
mIv.setScaleX(0.5f+value/200);
mIv.setScaleY(0.5f+value/200);
}
});
animator.start();
这里可以监听ObjectAnimator执行期间所用到的变量的值,根据这个值来设置第二个动画。第二种方法是ValueAnimator其实和第一种方法一样。
ValueAnimator animator = ValueAnimator.ofFloat(0f, 100f);
animator.setDuration(200);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();//得到0f~100f当中的这个时间点对应的值
mIv.setScaleX(0.5f + value / 200);
mIv.setScaleY(0.5f + value / 200);
}
});
animator.start();
这里也是通过添加监听实现自己想要的动画。第三种是PropertyValuesHolder。
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha", 1f, 0.5f, 1f);
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0.5f, 1f);
PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0.5f, 1f);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mIv, holder1, holder2, holder3);
animator.setDuration(200);
animator.start();
第四种是最常用的AnimatorSet。
ObjectAnimator animator1 = ObjectAnimator.ofFloat(mIv, "translationX", 0f, 100f, 0f);
//animator1.setRepeatCount(3);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(mIv, "alpha", 0f, 1f);
//animator2.setStartDelay(startDelay)//设置延迟执行 动画的间隔时间
ObjectAnimator animator3 = ObjectAnimator.ofFloat(mIv, "scaleX", 0f, 2f, 1f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(500);
//animatorSet.play(animator3).with(animator2).after(animator1);//animator1在前面
animatorSet.play(animator3).with(animator2).before(animator1);//animator1在后面
//animatorSet.playTogether(animator1,animator2,animator3);//一起进行
//animatorSet.playSequentially(animator1, animator2, animator3);//顺序播放
animatorSet.start();
AnimatorSet还是比较灵活的,用法比较多。接下来看一下TypeEvaluator估值器,它可以控制view轨迹运动。
/**
* x: 匀速
* y: 加速度 y=vt=1/2*g*t*t
* 估值器---控制坐标PointF(x,y)
*/
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(2000);
valueAnimator.setObjectValues(new PointF(0, 0));
final PointF pointF = new PointF();
valueAnimator.setEvaluator(new TypeEvaluator() {
@Override
public PointF evaluate(float fraction, PointF startValue,
PointF endValue) {
// 估值计算方法---可以在执行的过程当中干预改变属性的值---做效果:用自己的算法来控制
//不断地去计算修改坐标
//x匀速运动 x=v*t 为了看起来效果好我让t变成fraction*5
pointF.x = 100f * (fraction * 5);
//加速度 y=vt=1/2*g*t*t
// pointF.y = 0.5f*9.8f*(fraction*5)*(fraction*5);
pointF.y = 5f * 0.5f * 9.8f * (fraction * 5) * (fraction * 5);
return pointF;
}
});
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF f = (PointF) animation.getAnimatedValue();
mIv.setX(f.x);
mIv.setY(f.y);
}
});
valueAnimator.start();
}
});
估值器就是设置Evaluator通过一定的算法返回X,Y让View进行移动。
最后就是插值器这里只写出几种。
ObjectAnimator oa = ObjectAnimator.ofFloat(mIv, "translationY", 0f, 800f);
oa.setDuration(800);
oa.setInterpolator(new AccelerateInterpolator(1));//加速
oa.setInterpolator(new AccelerateDecelerateInterpolator());//先加速后减速
oa.setInterpolator(new BounceInterpolator());//回弹
oa.setInterpolator(new AnticipateInterpolator());//先后撤一下然后正常进行
oa.setInterpolator(new CycleInterpolator(1));//周期执行
oa.start();
这里只是属性动画基本的一个概括,和个人的一个总结,如果其中有错误还请指出,我会尽快修改文章,并改正自己的理解,谢谢。