一、属性动画
什么是属性动画:
属性动画是从3.0及以后出现的(如果要兼容低版本,可以使用一个民间版第三方的一个jar NineOldAndroid.jar,用法跟系统的用法差不多)。
不断地控制控件的属性变化达到动画的效果,一般我们是一些组合的属性动画达到复杂的效果。
以前都是:补间动画BetweenAnimation、帧动画FrameAnimation
比较之前的View动画,属性动画更加丰富、好用;
属性动画是真实地改变控件的属性,view动画是个假象,平移以后的原来位置还是可以点击的。
button.setTranslationX(100);
二、三种动画的比较
1.补间动画(Tween Animation)
①. 渐变动画支持四种类型:平移(Translate)、旋转(Rotate)、缩放(Scale)、不透明度(Alpha)。
②. 只是显示的位置变动,View的实际位置未改变,表现为View移动到其他地方,点击事件仍在原处才能响应。
③. 组合使用步骤较复杂。
④. View Animation 也是指此动画。
// 补间动画
Animation animation = AnimationUtils.loadAnimation(this,
R.anim.translate);
animation.start();
image_header.startAnimation(animation);
2.帧动画(Frame Animation)
①. 用于生成连续的Gif效果图。
②. DrawableAnimation也是指此动画。
3.属性动画(Property Animation)
①. 支持对所有View能更新的属性的动画(需要属性的setXxx()和getXxx())。
②. 更改的是View实际的属性,所以不会影响其在动画执行后所在位置的正常使用。
③. Android3.0 (API11)及以后出现的功能,3.0之前的版本可使用github第三方开源库nineoldandroids.jar进行支持。
// 1.属性动画
position += 100;
view.setTranslationX(position);
view.setAlpha((float) Math.random());
三.属性动画常用API
ObjectAnimator :对象动画执行类。
PropertyValuesHolder : 属性存储器,为两个执行类提供更新多个属性的功能。
AnimatorListener :动画执行监听,在动画开始、重复、结束、取消时进行回调。
Keyframe :为 PropertyValuesHolder提供多个关键帧的操作值。
AnimatorSet :一组动画的执行集合类:设置执行的先后顺序,时间等。
TimeInterpolator :时间插值,用于控制动画执行过程。
ValueAnimator :值动画执行类,常配合AnimatorUpdateListener使用。
AnimatorUpdateListener :动画更新监听。
TypeEvaluator :类型估值,用于设置复杂的动画操作属性的值。
四、常用的动画
1)translationX 和 translationY:这两个属性控制了View所处的位置,它们的值是由layout容器设置的,是相对于坐标原点(0,0左上角)的一个偏移量。
2)rotation, rotationX 和 rotationY:控制View绕着轴点(pivotX和pivotY)旋转。
3)scaleX 和 scaleY:控制View基于pivotX和pivotY的缩放。
4)pivotX 和 pivotY:旋转的轴点和缩放的基准点,默认是View的中心点。
5)x 和 y:描述了view在其父容器中的最终位置,是左上角左标和偏移量(translationX,translationY)的和。
6)aplha:透明度,1是完全不透明,0是完全透明。
五、使用方式
1.改变对象的属性值
ObjectAnimator oa = ObjectAnimator.ofFloat(v, "translationX", 0f,300f);
oa.setDuration(500);
oa.start();
ObjectAnimator oa = ObjectAnimator.ofFloat(v, "translationY", 0f,300f);
oa.setDuration(500);
oa.start();
ObjectAnimator oa = ObjectAnimator.ofFloat(v, "rotationX", 0f,360f);
oa.setDuration(500);
oa.start();
2.多个动画同时执行
(1)方法1:设置动画监听,开始第一个动画同时开启其他动画
ObjectAnimator animator = ObjectAnimator.ofFloat(image_header, "haha",
0f, 100f);// 没有这个属性的时候,就是valueanimator
animator.setDuration(300);
// 设置动画监听
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 动画在执行的过程当中,不断地调用此方法
// animation.getAnimatedFraction()//百分比
// 得到duration时间内 values当中的某一个中间值。0f~100f
float value = (Float) animation.getAnimatedValue();//
image_header.setScaleX(0.5f + value / 200);// 0.5~1
image_header.setScaleY(0.5f + value / 200);// 0.5~1
}
});
animator.start();
animator.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animator animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animator animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationCancel(Animator animation) {
// TODO Auto-generated method stub
}
});
(2).方法2:用ValueAnimator
ValueAnimator animator = ValueAnimator.ofFloat(0f, 200f);
animator.setDuration(200);
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 动画在执行的过程当中,不断地调用此方法
// animation.getAnimatedFraction()//百分比
// 得到duration时间内 values当中的某一个中间值。0f~100f
float value = (Float) animation.getAnimatedValue();//
image_header.setScaleX(0.5f + value / 200);// 0.5~1
image_header.setScaleY(0.5f + value / 200);// 0.5~1
}
});
animator.start();
(3)方法3:PropertyValuesHolder
//float... values:代表关键帧的值
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha",
1f, 0.7f, 1f);
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX",
1f, 0.7f, 1f);
PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY",
1f, 0.7f, 1f);
// PropertyValuesHolder holder3 =
PropertyValuesHolder.ofFloat("translationX", 0f, 300f);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(image_header,
holder1, holder2, holder3);
animator.setDuration(1000);
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// TODO Auto-generated method stub
float animatedValue = (Float) animation.getAnimatedValue();
float animatedFraction = animation.getAnimatedFraction();
long playTime = animation.getCurrentPlayTime();
System.out.println("animatedValue:" + animatedValue
+ ", playTime:" + playTime);
}
});
animator.start();
(4)方法4:动画集合
ObjectAnimator animator1 = ObjectAnimator.ofFloat(image_header, "alpha", 1f,
0.7f, 1f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(image_header, "scaleX", 1f,
0.7f, 1f);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(image_header, "scaleY", 1f,
0.7f, 1f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(500);
// animatorSet.play(anim);//执行当个动画
// animatorSet.playTogether(animator1,animator2,animator3);//同时执行
animatorSet.playSequentially(animator1, animator2, animator3);// 依次执行动画
animatorSet.start();
3.实现抛物线效果
/**
* x:匀速
* y:加速度 y=1/2*g*t*t
* 使用估值器最好实现。
*/
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(4000);
// valueAnimator.setFloatValues(values)
valueAnimator.setObjectValues(new PointF(0, 0));
//估值器---定义计算规则
valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {
@Override
public PointF evaluate(float fraction, PointF startValue,
PointF endValue) {
//拿到每一个时间点的坐标
//x=v*t (s秒)
PointF pointF = new PointF();
pointF.x = 100f*(fraction*4);//初始速度*(执行的百分比*4)
// pointF.y = 0.5f*9.8f*(fraction*4)*(fraction*4);
pointF.y = 0.5f*150f*(fraction*4)*(fraction*4);
return pointF;
}
});
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//得到此时间点的坐标
PointF pointF = (PointF) animation.getAnimatedValue();
image_header.setX(pointF.x);
image_header.setY(pointF.y);
}
});
valueAnimator.start();
六、插值器Interpolator
//插值器
ObjectAnimator oa = ObjectAnimator.ofFloat(image_header, "translationY", 0f,800f);
oa.setDuration(500);
//设置加速器---
// oa.setInterpolator(new AccelerateInterpolator(5));
// oa.setInterpolator(new AccelerateDecelerateInterpolator());
// oa.setInterpolator(new AnticipateInterpolator(8));
// oa.setInterpolator(new OvershootInterpolator());
// oa.setInterpolator(new CycleInterpolator(4));
oa.setInterpolator(new BounceInterpolator());
oa.start();
(1).AccelerateDecelerateInterpolator 加速减速插值器 :
(2).AccelerateInterpolator 加速插值器:
(3).AnticipateInterpolator 回荡秋千插值器 :
(4).AnticipateOvershootInterpolator:
(5).BounceInterpolator 弹跳插值器:
(6).CycleInterpolator 正弦周期变化插值器 :
(7).DecelerateInterpolator 减速插值器:
(8).OvershootInterpolator: