Android3.0之前有两种动画,一种方式是补间动画 Tween Animation、另一种叫逐帧动画 Frame Animation(也称Drawable Animation )Android3.0以后增加了属性动画 Property Animation。Tween Animation、Frame Animation只能用于View,被归类为View Animation。
一、1、View Animation
视图动画提供:AlphaAnimation、RotateAniamtion、TranslateAniamtion、ScaleAnimation四种动画方式。
<1>AlphaAnimation透明度动画
AlphaAnimation
extends Animationjava.lang.Object | ||
↳ | android.view.animation.Animation | |
↳ | android.view.animation.AlphaAnimation |
<span style="font-size:18px;">AlphaAnimation alphaAnimation = new AlphaAniamtion(0,1);
alphaAnimation.setDuration(1000);
view.startAnimation(alphaAnimation);</span>
res/anim/
<span style="font-size:18px;"><alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"/></span>
<2>RotateAnimation旋转动画
RotateAnimation
extends Animationjava.lang.Object | ||
↳ | android.view.animation.Animation | |
↳ | android.view.animation.RotateAnimation |
RotateAnimation(float fromDegrees, float toDegrees) Constructor to use when building a RotateAnimation from code. |
RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) Constructor to use when building a RotateAnimation from code | |
RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) Constructor to use when building a RotateAnimation from code |
<span style="white-space:pre"> </span>btn = (Button)findViewById(R.id.b);rotateAnimation2 = new RotateAnimation(0f,1080f,RotateAnimation.RELATIVE_TO_SELF,0.5f,RotateAnimati on.RELATIVE_TO_SELF,0.5f);btn.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stubrotateAnimation2.setInterpolator(new OvershootInterpolator());rotateAnimation2.setDuration(3000);btn.setAnimation(rotateAnimation2);btn.startAnimation(rotateAnimation2);} });
res/anim
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"android:fromDegrees="0"android:pivotX="50%"android:pivotY="50%"android:toDegrees="1080.0"><shapeandroid:innerRadiusRatio="3"android:shape="ring"android:thicknessRatio="8"android:useLevel="false"><gradientandroid:endColor="#2F90BD"android:startColor="#FFFFFF"android:type="sweep" /></shape>
</rotate>
<!-- 放在anim文件夹下,AnimationUtils.loadAnimation(this, R.anim.shape_ring);
image.startAnimation(animation);
<3>TranslateAniamtion位移动画
TranslateAnimation
extends Animationjava.lang.Object | ||
↳ | android.view.animation.Animation | |
↳ | android.view.animation.TranslateAnimation |
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) Constructor to use when building a TranslateAnimation from code |
TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue) Constructor to use when building a TranslateAnimation from code |
<span style="font-size:18px;">TranslateAnimation translateAnimation = new TranslateAnimation(0,200,0,300);
translationAnimation.setDuration(1000);
view.startAniamtion(translateAniamtion);</span>
res/anim
<span style="font-size:18px;"> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> </span>
<4>ScaleAniamtion缩放动画
ScaleAnimation
extends Animationjava.lang.Object | ||
↳ | android.view.animation.Animation | |
↳ | android.view.animation.ScaleAnimation |
ScaleAnimation(float fromX, float toX, float fromY, float toY) Constructor to use when building a ScaleAnimation from code |
ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) Constructor to use when building a ScaleAnimation from code | |
ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) Constructor to use when building a ScaleAnimation from code |
ScaleAniamtion scaleAniamtion = new ScaleAniamtion(0,1,0,1,Animation.RELATIVE_TO_SELF,0.5F,Animation.RELATIVE_TO_SELF,0.5F);
scaleAniamtion.setDuration(1000);
view.startAniamtion(scaleAnimation);
res/anim
<scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" />
动画集合AnimationSet
AnimationSet
extends Animationjava.lang.Object | ||
↳ | android.view.animation.Animation | |
↳ | android.view.animation.AnimationSet |
AnimationSet(boolean shareInterpolator)
AnimationSet set = new AnimationSet(true);button2 = (Button)findViewById(R.id.b5);button2.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){set.addAnimation(alphaAnimation);set.addAnimation(rotateAnimation);set.setDuration(3000);button2.startAnimation(set);}});//动画集
res/anima
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set>
</set>
在java代码中使用:
ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);
2、Drawable Animation逐帧动画
可以使用多幅图片实现动画效果。
首先定义一个以 <animation-list>为根节点的xml文件,命名为 anim.xml 放在 res/drawable/目录下。
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true"> <item android:drawable="@drawable/image1" android:duration="200" /> <item android:drawable="@drawable/image2" android:duration="200" /> <item android:drawable="@drawable/image3" android:duration="200" />
</animation-list>
对控件中使用此动画:
ImageView image = (ImageView) findViewById(R.id.rocket_image);
image.setBackgroundResource(R.drawable.rocket_thrust);
AnimationDrawable animation = (AnimationDrawable) image.getBackground();
animation.start();
3、视图动画的监听
animation.setAnimationListener(new AnimationListener(){@Overridepublic void onAnimationStart(Animation animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationEnd(Animation animation) {// TODO Auto-generated method stubmHandler.post(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubIntent intent = new Intent(WelcomActivity.this,MainActivity.class);startActivity(intent);WelcomActivity.this.finish();}});}
视图动画实现原理:每次绘制视图时,View所在的ViewGroup中的drawChild()函数获取该View的Animation的Transformation值,然后调用canvas.concat(transformToApply.getMatrix());通过矩阵完成动画帧。若动画没有完成就调用invalidate()函数,启动下次绘制来驱动动画,从而完成整个动画绘制。
视图动画一个非常大的缺陷:当view发生视图动画后,其相应事件的位置还在动画前的地方,不具备交互性。优点:效率高、使用方便。
二、PropertyAnimation属性动画PropertyAnimation是通过修改控件的属性实现的动画,基本上可以实现所有动画效果,并且可以交互。
常用的属性动画:ObjectAnimator、AnimatorSet(PropertyValuesHolder也可以实现类似效果)、ValueAnimator、TimeAnimator...
1、ObjectAnimator
ObjectAnimator
extends ValueAnimatorjava.lang.Object | |||
↳ | android.animation.Animator | ||
↳ | android.animation.ValueAnimator | ||
↳ | android.animation.ObjectAnimator |
static <T> ObjectAnimator | ofFloat(T target,Property<T, Float> property, float... values) Constructs and returns an ObjectAnimator that animates between float values. |
static ObjectAnimator | ofFloat(Object target,String propertyName, float... values) Constructs and returns an ObjectAnimator that animates between float values. |
static <T> ObjectAnimator | ofInt(T target,Property<T, Integer> property, int... values) Constructs and returns an ObjectAnimator that animates between int values. |
static ObjectAnimator | ofInt(Object target,String propertyName, int... values) Constructs and returns an ObjectAnimator that animates between int values. |
static <T, V> ObjectAnimator | ofObject(T target,Property<T, V> property,TypeEvaluator<V> evaluator, V... values) Constructs and returns an ObjectAnimator that animates between Object values. |
static ObjectAnimator | ofObject(Object target,String propertyName, TypeEvaluator evaluator,Object... values) Constructs and returns an ObjectAnimator that animates between Object values. |
static ObjectAnimator | ofPropertyValuesHolder(Object target,PropertyValuesHolder... values) Constructs and returns an ObjectAnimator that animates between the sets of values specified in PropertyValueHolder objects. |
objectAnimator = ObjectAnimator.ofFloat(view, "translationX", 300);
参数包括一个实施动画的对象target(eg.view),target的属性名(eg.translationX),第三个参数是一个可变数组参数,传入该属性值变化的过程,但这个属性必须有get和set函数,否则ObjectAnimator无法有作用,内部会通过java反射机制来调用set函数修改对象的属性值。例:平移动画
objectAnimator = ObjectAnimator.ofFloat(view, "translationX", 300);
objectAnimator.setRepeatCount(3);//ObjectAnimator.INFINITE
//objectAnimator.setDuration(3000);//设置setRepeatCount后Duration不起作用了
objectAnimator.start();
常用的可以直接使用的属性动画的属性值:
- translationX、translationY:作为一种增量控制View对象从它布局容器的左上角坐标偏移的位置。
- rotation、rotationX、rotationY:target绕它的支点进行2D、3D旋转。
- scaleX、scaleY:target绕它的支点进行2D缩放。
- pivotX、pivotY:控制这target的支点位置,围绕这个支点进行旋转和缩放处理。默认是target的中心。
- x、y:描述target在容器中的最终位置,是最初的左上角坐标和translationX、translationY值的和。
- alpha:target的透明度。默认1(不透明),0(完全透明,不可见)。
如果想要作用动画的对象没有get和set方法,可以通过自定义一个属性类或包装类间接的给这个属性添加get和set方法:为target添加一个height属性:
package sunny.example.helloandroidheroesxmlshape;
//自定义一个包装类,间接给要进行动画的view增加它本身没有的get、set属性
import android.view.View;
public class WrapperView {private View mTarget;public WrapperView(View v){this.mTarget = v;}public int getHeight(){return mTarget.getLayoutParams().height;}public void setHeight(int height){mTarget.getLayoutParams().height = height;mTarget.requestLayout();}
}
使用height属性:
objectAnimator1 = ObjectAnimator.ofInt(viewWrapper, "height", 100);//
objectAnimator1.setDuration(3000).start();
2、ValueAniamtor
ValueAnimator
extends Animatorjava.lang.Object | ||
↳ | android.animation.Animator | |
↳ | android.animation.ValueAnimator |
static ValueAnimator | ofFloat(float... values) Constructs and returns a ValueAnimator that animates between float values. |
static ValueAnimator | ofInt(int... values) Constructs and returns a ValueAnimator that animates between int values. |
static ValueAnimator | ofObject(TypeEvaluator evaluator,Object... values) Constructs and returns a ValueAnimator that animates between Object values. |
static ValueAnimator | ofPropertyValuesHolder(PropertyValuesHolder... values) Constructs and returns a ValueAnimator that animates between the values specified in the PropertyValuesHolder objects. |
ValueAniamtor valueAnimator = ValueAniamtor.ofFloat(0,100);
animator.setTarget(view);
animator.setDuration(3000).start();
aniamtor.addUpdateListener(new AnimatorUpdateListaner(){
@Override
public void onAniamtionUpdate(ValueAnimator animation){
Float value = (Float)animation.getAnimatedValue();}
});
3、AnimatorSet
AnimatorSet
extends Animatorjava.lang.Object | ||
↳ | android.animation.Animator | |
↳ | android.animation.AnimatorSet |
对一个target的属性作用多个动画效果,并可以控制各个动画执行顺序:
ObjectAniamtor animator1 = ObjectAnimator.ofFloat(view,"translationX",300f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(view,"scaleX",1f,0f,1f);
AnimationSet set = new AnimationSet();
set.setDuration(3000);
//set.play(animator1).after(animator2);
//set.playTogether(animator1,animator2);
//set.play(animator1).before(animator2);
//set.play(animator1).before(animator2).before(animator3);//此时时animator1结束后会同时play animator2和3
set.playSequentially(animator1,animator2);//1结束后执行2
set.start();
4、PropertyValuesHolder
public class
PropertyValuesHolder
extends Objectimplements Cloneable
类似视图动画AnimationSet,可以对target的多个属性作用动画:
h1 = PropertyValuesHolder.ofFloat("translationX", 300f);
h2 = PropertyValuesHolder.ofFloat("scaleY", 1f,0.5f);
h3 = PropertyValuesHolder.ofInt("alpha", 0,1);
ObjectAnimator.ofPropertyValuesHolder(view1,h1,h2,h3).start();
5、动画事件的监听
objectAnimator1.addListener(new AnimatorListener(){@Overridepublic void onAnimationStart(Animator animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationEnd(Animator animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationCancel(Animator animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animator animation) {// TODO Auto-generated method stub}});
6、在XML中使用属性动画:
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="1000"android:propertyName="scaleX"android:valueFrom="1.0"android:valueTo="2.0"android:valueType="floatType" ></objectAnimator>
在程序中使用XML中定义的动画:
public void scaleX(View v){
Animator ani = AnimatorInflater.loadAnimator(this,R.animator.scaleX);
ani.setTarget(mButton);
ani.start();}
github:https://github.com/HiSunny/HelloAnimation.git