您的位置:首页 > 移动开发 > Android开发

Android动画之---属性动画

2016-07-18 02:13 465 查看
什么是属性动画?

属性动画就是一段时间内对某个对象的属性(可以是多个)进行操作,产生一系列动画效果。

属性动画那些优势?

1.它可以作用于任何对象,而传统意义上的视图动画只能作用于View.

2.它可以制作的动画效果要丰富的多,因为是对属性的操作,可以实现任意的动画效果.

3.在性能上 ,属性动画更加高效并节省系统资源,本质上只是改变某个对象的属性,而视图动画本质上是在View的onDraw方法中对动画效果的重绘。

4.新的属性动画框架可以响应用户的触摸时间,便于同用户交互,这是视图动画所不不具备的特性

属性动画使用的是Animator类.

属性动画要想兼容Android3.0以下的版本,就必须使用NineOldAndroids.jar架包,可到此处下载http://nineoldandroids.com/,这个包中的类和Android3.0以后的动画库中的类明称都差不多,所以我们只是学会Android3.0以后属性动画使用就可以一样使用这个库

首先介绍属性动画里面常用几个类:

ValueAnimator

属性动画中最基础的类,它本身不产生任何的动画效果,它比较像一个数值生成器,根据这个生成的数值,我们可以人为设置属性值(任意对象的),进而产生自己的动画的效果。

下面是一个改变View的背景属性的动画,使得View的背景是从红色变化到蓝色过程,它的大部分使用还是和视图动画差不多。

ValueAnimator valueAnimator = ValueAnimator.ofInt(0xFFFF8080, 0xFF8080FF);
valueAnimator.setDuration(3000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);//无数次
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);//从结尾返回到开始
valueAnimator.setEvaluator(new ArgbEvaluator());//设置类型估值器,这里是颜色估值器,也可以自己定义
/**
* ValueAnimator.AnimatorUpdateListener监听动画的数值变化
*/
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();//获取变化过程中的任意时刻的数值大小
v.setBackgroundColor(value);//这里是不是任意对象都可以在这里设置自己的属性!
}
});
valueAnimator.start();
}


看看运行效果:



ObjectAnimator

它是属性动画中使用最多的一个类,它是继承上面的ValueAnimator,因为是ValueAnimator比较原始,为了效率,就封装了ObjectAnimator类,它对于开发者来说更加高效。要想使用ObjectAnimator必须具备以下条件:

操作的对象的属性必须有get和set方法,而且是这个get和set都必须直接作用到这里属性上。

View中可以被操作的属性大体如下

alpha 渐变

rotation/rotationX / rotationY 围绕x和y轴的旋转

scaleX/**scaleY**x和y缩放

translationX/translationY x和y方向平移

x/y

操作实例如下:第一个参数目标View对象,第二个数属性

ObjectAnimator.ofFloat(v, "alpha", 0, 0.3f, 1.0f).setDuration(2000).start();
ObjectAnimator.ofFloat(v, "rotationX", 0, 180).setDuration(2000).start();
ObjectAnimator.ofFloat(v, "rotationY", 0, 180).setDuration(2000).start();
ObjectAnimator.ofFloat(v, "scaleX", 0, 1).setDuration(2000).start();
ObjectAnimator.ofFloat(v, "scaleY", 0, 1).setDuration(2000).start();
ObjectAnimator.ofFloat(v, "translationX", 100, 200).setDuration(2000).start();
ObjectAnimator.ofFloat(v, "translationY", 100, 200, 300).setDuration(2000).start();
ObjectAnimator.ofFloat(v, "rotation", 0, 180).setDuration(2000).start();
ObjectAnimator.ofFloat(v, "x", 100, 330).setDuration(2000).start();
ObjectAnimator.ofFloat(v, "y", 100, 330).setDuration(2000).start();


如果想要操作的某个属性没有get和set方法的话,这个时候可以使用上面ValueAnimator或者使用包装类。

比如Button按钮的宽度,下面我们看看实例:

public class WrapView {
private View view;

public WrapView(View view) {
this.view = view;
}

public void setWidth(int width) {
view.getLayoutParams().width = width;
view.requestLayout();
}

public int getWidth() {
return view.getLayoutParams().width;
}
}


这里get和set中操作width.

WrapView wrapButton = new WrapView(v);
ObjectAnimator.ofInt(wrapButton, "width", v.getWidth(), v.getWidth() + 200).setDuration(2000).start();


运行代码:



PropertyValuesHolderAnimatorSet

这两个都是用于操作一个对象的多个属性,区别只是AnimatorSet可以控制动画播放的顺序。

使用PropertyValuesHolder来进行属性动画设置

ObjectAnimator.ofPropertyValuesHolder(myView,
PropertyValuesHolder.ofFloat("rotationX", 0, 360),
PropertyValuesHolder.ofFloat("rotationY", 0, 180),
PropertyValuesHolder.ofFloat("rotation", 0, -90),
PropertyValuesHolder.ofFloat("translationX", 0, 90),
PropertyValuesHolder.ofFloat("translationY", 0, 90),
PropertyValuesHolder.ofFloat("scaleX", 1, 1.5f),
PropertyValuesHolder.ofFloat("scaleY", 1, 0.5f),
PropertyValuesHolder.ofFloat("alaph", 0.25f, 1)
).setDuration(5000).start();


使用AnimatorSet来进行属性动画设置

AnimatorSet set = new AnimatorSet();
set.playTogether( /**所有动画都播放*/
ObjectAnimator.ofFloat(myView, "rotationX", 0, 360), /**单个动画*/
ObjectAnimator.ofFloat(myView, "rotationY", 0, 180),
ObjectAnimator.ofFloat(myView, "rotation", 0, -90),
ObjectAnimator.ofFloat(myView, "translationX", 0, 90),
ObjectAnimator.ofFloat(myView, "translationY", 0, 90),
ObjectAnimator.ofFloat(myView, "scaleX", 1, 1.5f),
ObjectAnimator.ofFloat(myView, "scaleY", 1, 0.5f),
ObjectAnimator.ofFloat(myView, "alpha", 1, 0.25f, 1)
);
set.setDuration(5 * 1000).start();


AnimatorListenerAdapter和AnimatorListener

这两个是动画监听类

Animator用法:

ObjectAnimator anim = ObjectAnimator.ofFloat(myView, "rotationX", 0, 360);
anim.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) {

}
});


AnimatorListenerAdapter的用法,这个比较好,可以选择自己想要监听的动作,比如动画结束:

anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});


TypeEvaluator

这个是属性动画的类型估值器,它是一个接口,内部只有一个方法当我们在动画中设置了类型估值器以后,它获取动画某个时刻的某个属性值,这个是可以自定义,或使用系统的。

public interface TypeEvaluator<T> {
* @param fraction   The fraction from the starting to the ending values
* @param startValue The start value.
* @param endValue   The end value.
* @return A linear interpolation between the start and end values, given the
*         <code>fraction</code> parameter.
*/
public T evaluate(float fraction, T startValue, T endValue);
}


fraction:是指动画已发生时间占总时间的的百分比

startValue:是动画的起始值

endValue:是动画的结束值

TimeInterpolator

这是时间差值器,获取的是动画已发生时间占总时间的的百分比,就是上面的fraction。

public interface TimeInterpolator {

float getInterpolation(float input);
}


上面方法中我们可以认为的插一脚,所以叫插值器。通过自己对上面input的修改达到自己要求。

比如线性插值器,看源码;

public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {

public LinearInterpolator() {
}

public LinearInterpolator(Context context, AttributeSet attrs) {
}

public float getInterpolation(float input) {
return input;//这里直接返回了原值,并未改变,
}

/** @hide */
@Override
public long createNativeInterpolator() {
return NativeInterpolatorFactoryHelper.createLinearInterpolator();
}
}


上面可以看到线性插值器并未改变input值,如果是我们自己定义一个插值器的话,我们就可以更改这里了.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动画 android