首页 > 代码库 > Android Property Animation

Android Property Animation

Property Animation介绍: 

出生在3.0,是利用了View所拥有的属性,进行一系列的操作。比如一个View有什么样的setAbc的属性,那么理论上就可以设置它。

它不仅改变View的绘制,也改变了View的属性;而Tween Animation 只改变View的绘制。

ValueAnimator 为动画的基类,它有一个子类ObjectAnimator。需要Interpolator和TypeEvaluator来计算属性值。

Interpolator 时间插入器,动画的运动速率,参见上一篇Tween Animation

TypeEvaluator Animator的工厂方法 of方法能创建属性为任何值类型的对象。TypeEvaluator就是用来计算属性值的

3.0以后新增了一些View的属性:

1)translationX 和 translationY:这两个属性控制了View所处的位置,它们的值是由layout容器设置的,是相对于坐标原点(0,0左上角)的一个偏移量。

2)rotation, rotationX 和 rotationY:控制View绕着轴点(pivotX和pivotY)旋转。它的表现跟Tween Animation中的RotateAnimation不一致。

RotateAnimation 的旋转,表现为平面的旋转

而rotationX、Y 旋转,是立体的旋转,默认是以View的中心点,做x y的水平线,面向水平线进行翻转

3)scaleX 和 scaleY:控制View基于pivotX和pivotY的缩放。

4)pivotX 和 pivotY:旋转的轴点和缩放的基准点,默认是View的中心点。

5)x 和 y:描述了view在其父容器中的最终位置,是左上角左标和偏移量(translationX,translationY)的和。

6)aplha:透明度,1是完全不透明,0是完全透明。

以上这些属性与Tween Animation的动画属性值差不多

ObjectAnimator 对象动画

该动画,一次只能表示一个动作属性。

ObjectAnimator的xml实现

xml定义动画

res/animator/scale_object_animator.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:propertyName="scaleX"
    android:repeatCount="1"
    android:repeatMode="reverse"
    android:valueFrom="1.0"
    android:valueTo="2.0" >

</objectAnimator>

代码加载 动画xml

imageview_scale.setBackground(getResources().getDrawable(R.drawable.a11));
		ObjectAnimator scaleAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.scale_object_animator);
		scaleAnimator.setTarget(imageview_scale);//设置动画作用的目标对象
		scaleAnimator.setDuration(1000);
		scaleAnimator.setRepeatCount(50);
		scaleAnimator.start();

AnimatorSet 动画集

由ObjectAnimator 和 ValueAnimator 组成,对应的xml中的写法 类似为 <se> <objectAnimator />  <animator /> </set>

xml定义动画

res/animator/set_rotate_scale.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <set>
        <objectAnimator
            android:propertyName="rotationX"
            android:repeatCount="50"
            android:repeatMode="reverse"
            android:valueFrom="0"
            android:valueTo="20" />
        <objectAnimator
            android:propertyName="rotationY"
            android:repeatCount="50"
            android:repeatMode="reverse"
            android:valueFrom="0"
            android:valueTo="45"
            android:valueType="floatType" />
    </set>
    <set>
        <objectAnimator
            android:propertyName="scaleX"
            android:repeatCount="50"
            android:repeatMode="reverse"
            android:valueFrom="1.0"
            android:valueTo="2.0" >
        </objectAnimator>
        <objectAnimator
            android:propertyName="scaleY"
            android:repeatCount="50"
            android:repeatMode="reverse"
            android:valueFrom="1.0"
            android:valueTo="2.0" >
        </objectAnimator>
    </set>

</set>

代码加载 动画xml

imageview_rotate.setBackground(getResources().getDrawable(R.drawable.a11));
		AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.set_rotate_scale);
		animatorSet.setTarget(imageview_rotate);
		animatorSet.setDuration(1000);
		animatorSet.setInterpolator(new BounceInterpolator());//设置end时的弹跳插入器
		animatorSet.start();

PropertyValuesHolder

//使用PropertyValuesHolder 构造 Animator   组合成类似set的效果
		PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("scaleX",0f,2.5f);
		PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleY",0f,3f);     
		ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageview, pvhX,pvhY);
		animator.setDuration(2000);
		animator.start();

ViewPropertyAnimator

通过view.animate()来获取ViewPropertyAnimator

imageview.setBackground(getResources().getDrawable(R.drawable.a11));
		ViewPropertyAnimator animate = imageview.animate();//该对象没有setRepeat的方法
		//通过一些动画属性来设置 组合成类似set的效果
		animate.alpha(0);
		animate.rotationX(50);
		animate.translationXBy(500);
		animate.scaleX(1.5f);
		animate.scaleY(1.5f);
		animate.setInterpolator(new BounceInterpolator());
		animate.setDuration(2000);
		animate.start();

ValueAnimator

ValueAnimator代码和xml设置中 没有setPropertyName 因为不是操作对象,只是根据value进行某种动作
需要加监听器,监听值的变化 做相应的处理

xml定义动画

<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android" 
    android:interpolator="@android:anim/accelerate_interpolator"
    android:duration="10000"
    android:startOffset="1000"
    android:repeatCount="infinite"
    android:repeatMode="restart"
    android:valueFrom="1"
    android:valueTo="100"
    android:valueType="intType">

</animator>

代码加载 动画xml

ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.animator);
		valueAnimator.setTarget(tv_num);
		valueAnimator.setEvaluator(new TypeEvaluator<Integer>() {

			@Override 
			public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
				System.out.println("百分比,fraction:" + fraction);
				System.out.println("结果值:" + (int)((startValue + fraction * (endValue - startValue)) / 10 * 10));
			    return (int)((startValue + fraction * (endValue - startValue)) / 10 * 10);
			}
		});
		valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
			
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				//在onAnimationUpdate中 该值返回第一个动画的 当前帧的evaluate 值
				System.out.println("animation.getAnimatedValue()==" + animation.getAnimatedValue());
				tv_num.setText(animation.getAnimatedValue() + "");
			}
		});
//		valueAnimator.setInterpolator(new LinearInterpolator());
		valueAnimator.start();

Animator的监听器

AnimatorListener

new AnimatorListener() {
			
			@Override
			public void onAnimationStart(Animator animation) {
				
			}
			
			@Override
			public void onAnimationRepeat(Animator animation) {
				
			}
			
			@Override
			public void onAnimationEnd(Animator animation) {
				
			}
			
			@Override
			public void onAnimationCancel(Animator animation) {
				
			}
		}

AnimatorListenerAdapter

new AnimatorListenerAdapter() {//空实现了AnimatorListener

			@Override
			public void onAnimationCancel(Animator animation) {
				super.onAnimationCancel(animation);
			}

			@Override
			public void onAnimationEnd(Animator animation) {
				super.onAnimationEnd(animation);
			}

			@Override
			public void onAnimationRepeat(Animator animation) {
				super.onAnimationRepeat(animation);
			}

			@Override
			public void onAnimationStart(Animator animation) {
				super.onAnimationStart(animation);
			}

			@Override
			public void onAnimationPause(Animator animation) {
				super.onAnimationPause(animation);
			}

			@Override
			public void onAnimationResume(Animator animation) {
				super.onAnimationResume(animation);
			}
			
		}

AnimatorUpdateListener

new AnimatorUpdateListener() {
			
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				//在onAnimationUpdate中 该值返回第一个动画的 当前帧的evaluate 值
				System.out.println("animation.getAnimatedValue()==" + animation.getAnimatedValue());
			}
}

一些操作函数:animator.pause();  animator.resume();animator.reverse(); animator.end();animator.cancel();

animator.start();animator.isStarted();animator.isPaused();animator.isRunning();


用属性动画换背景色

详见ApiDemo要下的 BouncingBalls.java

private static final int RED = 0xffFF8080;
private static final int BLUE = 0xff8080FF;
private static final int CYAN = 0xff80ffff;
private static final int GREEN = 0xff80ff80;

{
	//动画 变色  
	ObjectAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", CYAN, BLUE, RED);
	colorAnim.setTarget(ll_animation);
	colorAnim.setEvaluator(new ArgbEvaluator());
	colorAnim.setRepeatCount(ValueAnimator.INFINITE);
	colorAnim.setRepeatMode(ValueAnimator.REVERSE);
	colorAnim.setDuration(3000);
	colorAnim.start();
}