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透明度动画
java.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旋转动画
java.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(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
rotateAnimation2.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">
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:thicknessRatio="8"
android:useLevel="false">
<gradient
android:endColor="#2F90BD"
android:startColor="#FFFFFF"
android:type="sweep" />
</shape>
</rotate>
<!-- 放在anim文件夹下,AnimationUtils.loadAnimation(this, R.anim.shape_ring);
image.startAnimation(animation);
<3>TranslateAniamtion位移动画
java.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缩放动画
java.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
java.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(){
@Override
public 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(){
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
mHandler.post(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Intent 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
java.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
java.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
java.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(){
@Override
public void onAnimationStart(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
}
@Override
public 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