Android动画分类汇总

Android动画相比大家都会用,这篇文章主要帮助大家了解Android中动画的分类。Animation下分为View Animation 和 3.0后加入的Property Animation。具体看图。那些名词都是些概念性的词语,不是对象。

Android动画分类汇总_第1张图片

一.View Animation


Animation的子类就包括AlphaAnimation、TranslateAnimation、ScaleAnimation、RotateAnimation,分别代表透明度,平移,伸缩,旋转。

public abstract class

Animation

extends  Object
implements  Cloneable
java.lang.Object
   ↳ android.view.animation.Animation
Known Direct Subclasses

1.Tween Animation(补间动画)大概用法如下

①JAVA代码中用法:

AlphaAnimation:
//创建一个AnimationSet对象,参数为Boolean型,
           //true表示使用Animation的interpolator,false则是使用自己的
           AnimationSet animationSet = new AnimationSet(true);
           //创建一个AlphaAnimation对象,参数从完全的透明度,到完全的不透明
           AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
           //设置动画执行的时间
           alphaAnimation.setDuration(500);
           //将alphaAnimation对象添加到AnimationSet当中
           animationSet.addAnimation(alphaAnimation);
           //使用ImageView的startAnimation方法执行动画
           image.startAnimation(animationSet);

RotateAnimation :
	   //参数1:从哪个旋转角度开始
           //参数2:转到什么角度
           //后4个参数用于设置围绕着旋转的圆的圆心在哪里
           //参数3:确定x轴坐标的类型,有ABSOLUT绝对坐标、RELATIVE_TO_SELF相对于自身坐标、RELATIVE_TO_PARENT相对于父控件的坐标
           //参数4:x轴的值,0.5f表明是以自身这个控件的一半长度为x轴
           //参数5:确定y轴坐标的类型
           //参数6:y轴的值,0.5f表明是以自身这个控件的一半长度为x轴
           RotateAnimation rotateAnimation = new RotateAnimation(0, 360,
                  Animation.RELATIVE_TO_SELF,0.5f,
                  Animation.RELATIVE_TO_SELF,0.5f);
           rotateAnimation.setDuration(1000);
           animationSet.addAnimation(rotateAnimation);
           image.startAnimation(animationSet);

ScanleAnimation:
AnimationSet animationSet = new AnimationSet(true);
           //参数1:x轴的初始值
           //参数2:x轴收缩后的值
           //参数3:y轴的初始值
           //参数4:y轴收缩后的值
           //参数5:确定x轴坐标的类型
           //参数6:x轴的值,0.5f表明是以自身这个控件的一半长度为x轴
           //参数7:确定y轴坐标的类型
           //参数8:y轴的值,0.5f表明是以自身这个控件的一半长度为x轴
           ScaleAnimation scaleAnimation = new ScaleAnimation(
                  0, 0.1f,0,0.1f,
                  Animation.RELATIVE_TO_SELF,0.5f,
                  Animation.RELATIVE_TO_SELF,0.5f);
           scaleAnimation.setDuration(1000);
           animationSet.addAnimation(scaleAnimation);
           image.startAnimation(animationSet);

TranslateAnimation:
AnimationSet animationSet = new AnimationSet(true);
           //参数1~2:x轴的开始位置
           //参数3~4:y轴的开始位置
           //参数5~6:x轴的结束位置
           //参数7~8:x轴的结束位置
           TranslateAnimation translateAnimation =
              new TranslateAnimation(
                  Animation.RELATIVE_TO_SELF,0f,
                  Animation.RELATIVE_TO_SELF,0.5f,
                  Animation.RELATIVE_TO_SELF,0f,
                  Animation.RELATIVE_TO_SELF,0.5f);
           translateAnimation.setDuration(1000);
           animationSet.addAnimation(translateAnimation);
           image.startAnimation(animationSet);


大致就是这样,实例化view之后设置view.startAnimation即可


②XML中使用

注意:Tween Animation在XML了使用动画这个文件夹有要求,与Frame Animation 和 Property Animation都不同,要区分开来,后面会有介绍


1.res文件夹下建立一个anim文件夹;

 2.创建xml文件,并首先加入set标签,更改标签如下:

xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"

    android:interpolator="@android:anim/accelerate_interpolator">

set>


3.然后在set里面加入属性,例如




4.接下来在JAVA代码中调用

	Animation anim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.scalex);
		view.startAnimation(anim);

简单的就是这样,也可以在set中加入其他的属性。回到这个标签。 它有两个属性,android:interpolator代表一个插值器资源,可以引用系统自带插值器资源,也可以用自定义插值器资源,默认值是匀速插值器。android:shareInterpolator代表里面的多个动画是否要共享插值器,默认值为true,即共享插值器,如果设置为false,那么的插值器就不再起作用,我们要在每个动画中加入插值器。

首先要了解为什么需要插值器,因为在补间动画中,我们一般只定义关键帧(首帧或尾帧),然后由系统自动生成中间帧,生成中间帧的这个过程可以成为“插值”。插值器定义了动画变化的速率,提供不同的函数定义变化值相对于时间的变化规则,可以定义各种各样的非线性变化函数,比如加速、减速等。下面是几种常见的插值器:

Interpolator对象 资源ID 功能作用
AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 先加速再减速
AccelerateInterpolator @android:anim/accelerate_interpolator 加速
AnticipateInterpolator @android:anim/anticipate_interpolator 先回退一小步然后加速前进
AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 在上一个基础上超出终点一小步再回到终点
BounceInterpolator @android:anim/bounce_interpolator 最后阶段弹球效果
CycleInterpolator @android:anim/cycle_interpolator 周期运动
DecelerateInterpolator @android:anim/decelerate_interpolator 减速
LinearInterpolator @android:anim/linear_interpolator 匀速
OvershootInterpolator @android:anim/overshoot_interpolator 快速到达终点并超出一小步最后回到终点

如果在一个set标签中包含多个动画效果,如果想让这些动画效果共享一个Interpolator

    android:shareInterpolator="true"

如果不想共享一个interpolator,则设置android:shareInterpolator="false"并且需要在每一个动画效果处添加interpolator


现在我们要实现一个不停旋转的东西,类似于刷新那样的图标,靠设置0~360度,repeatCount还是不够的,还要设置他的速度,如果是加入情况则看起来效果就不理想,此时的动画速度就应该是匀速状态。

刷新图标的旋转



    
具体根据需要去设置,此外也有自定义的插值器。

2.Frame Animation(逐帧动画)。


1.res文件夹下建立一个drawable或者anim或者animation文件夹;试过好像没问题

2.创建xml文件,根标签为相当于一个图片动画集合

eg:



    1000"/>
    1000"/>
    
    
    
    
效果是每秒换张drawable,可以自己试试

3.JAVA中

imageView.setBackgroundResource(R.drawable.anim);
           AnimationDrawable animationDrawable = (AnimationDrawable)
              imageView.getBackground();
           animationDrawable.start();

Frame Animation也是用的比较少的。




3.Property Animation(属性动画)。


Property Animation故名思议就是通过动画的方式改变对象的属性了

这里可以去看,里面详细点
http://blog.csdn.net/lmj623565791/article/details/38067475

eg:

ObjectAnimator实现动画

之所以选择ObjectAnimator为第一个~~是因为,这个实现最简单~~一行代码,秒秒钟实现动画,下面看个例子:
布局文件:

      
Activity中的调用
 public void rotateyAnimRun(View view)  
    {  
         ObjectAnimator//  
         .ofFloat(view, "rotationX", 0.0F, 360.0F)//  
         .setDuration(500)//  
         .start();  
    }  

是不是一行代码就能实现简单的动画~~

对于ObjectAnimator

1、提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束、以及中间的任意个属性值。

当对于属性值,只设置一个的时候,会认为当然对象该属性的值为开始(getPropName反射获取),然后设置的值为终点。如果设置两个,则一个为开始、一个为结束~~~

动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新某个属性,必须得有getter(设置一个属性值的时候)和setter方法~

2、如果你操作对象的该属性方法里面,比如上例的setRotationX如果内部没有调用view的重绘,则你需要自己按照下面方式手动调用。

[java]  view plain  copy
  1. anim.addUpdateListener(new AnimatorUpdateListener()  
  2.         {  
  3.             @Override  
  4.             public void onAnimationUpdate(ValueAnimator animation)  
  5.             {  
  6. //              view.postInvalidate();  
  7. //              view.invalidate();  
  8.             }  
  9.         });  
3、看了上面的例子,因为设置的操作的属性只有一个,那么如果我希望一个动画能够让View既可以缩小、又能够淡出(3个属性scaleX,scaleY,alpha),只使用ObjectAnimator咋弄?

想法是不是很不错,可能会说使用AnimatorSet啊,这一看就是一堆动画塞一起执行,但是我偏偏要用一个ObjectAnimator实例实现呢~下面看代码:

[java]  view plain  copy
  1. public void rotateyAnimRun(final View view)  
  2. {  
  3.     ObjectAnimator anim = ObjectAnimator//  
  4.             .ofFloat(view, "zhy"1.0F,  0.0F)//  
  5.             .setDuration(500);//  
  6.     anim.start();  
  7.     anim.addUpdateListener(new AnimatorUpdateListener()  
  8.     {  
  9.         @Override  
  10.         public void onAnimationUpdate(ValueAnimator animation)  
  11.         {  
  12.             float cVal = (Float) animation.getAnimatedValue();  
  13.             view.setAlpha(cVal);  
  14.             view.setScaleX(cVal);  
  15.             view.setScaleY(cVal);  
  16.         }  
  17.     });  
  18. }  

把设置属性的那个字符串,随便写一个该对象没有的属性,就是不管~~咱们只需要它按照时间插值和持续时间计算的那个值,我们自己手动调用~

效果:

这个例子就是想说明一下,有时候换个思路不要被API所约束,利用部分API提供的功能也能实现好玩的效果~~~

比如:你想实现抛物线的效果,水平方向100px/s,垂直方向加速度200px/s*s ,咋实现呢~~可以自己用ObjectAnimator试试~

4、其实还有更简单的方式,实现一个动画更改多个效果:使用propertyValuesHolder,类似于AnimationSet

[java]  view plain  copy
  1. public void propertyValuesHolder(View view)  
  2.     {  
  3.         PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,  
  4.                 0f, 1f);  
  5.         PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,  
  6.                 0, 1f);  
  7.         PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,  
  8.                 0, 1f);  
  9.         ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY,pvhZ).setDuration(1000).start();  
  10.     }  


对于ValueAnimator,它不像ObjectAniamtor那么耀眼,但它却是属性动画的核心,ObjectAnimator也是继承自ValueAnimator

ValueAnimator本身不提供任何的动画效果,它更像一个数值发生器,用来产生具有一定规律的数字,从而让调用者来控制动画的实现过程,ValueAnimator的一般使用为,在ValueAnimator的AnimatorUpdateListener中监听数值的变化,从而完成动画的变换。

ValueAnimator animator = ValueAnimator.ofFloat(0 , 100);
animator.setTarget(view);
animator.setDuration(1000).start();
animator.addUpdateListener(new AnimatorUpdateListener()){
	@override
	public void onAnimationUpdate(ValueAnimator animator){
		//得到动画执行过程中的数据变换
		Float value = (Float) animation.getAnimatedValue();
		//用户操作
	}
}

监听动画的事件

对于动画,一般都是一些辅助效果,比如我要删除个元素,我可能希望是个淡出的效果,但是最终还是要删掉,并不是你透明度没有了,还占着位置,所以我们需要知道动画如何结束。

所以我们可以添加一个动画的监听:

[java]  view plain  copy
  1. public void fadeOut(View view)  
  2.     {  
  3.         ObjectAnimator anim = ObjectAnimator.ofFloat(mBlueBall, "alpha"0.5f);  
  4.           
  5.         anim.addListener(new AnimatorListener()  
  6.         {  
  7.   
  8.             @Override  
  9.             public void onAnimationStart(Animator animation)  
  10.             {  
  11.                 Log.e(TAG, "onAnimationStart");  
  12.             }  
  13.   
  14.             @Override  
  15.             public void onAnimationRepeat(Animator animation)  
  16.             {  
  17.                 // TODO Auto-generated method stub  
  18.                 Log.e(TAG, "onAnimationRepeat");  
  19.             }  
  20.   
  21.             @Override  
  22.             public void onAnimationEnd(Animator animation)  
  23.             {  
  24.                 Log.e(TAG, "onAnimationEnd");  
  25.                 ViewGroup parent = (ViewGroup) mBlueBall.getParent();  
  26.                 if (parent != null)  
  27.                     parent.removeView(mBlueBall);  
  28.             }  
  29.   
  30.             @Override  
  31.             public void onAnimationCancel(Animator animation)  
  32.             {  
  33.                 // TODO Auto-generated method stub  
  34.                 Log.e(TAG, "onAnimationCancel");  
  35.             }  
  36.         });  
  37.         anim.start();  
  38.     }  

这样就可以监听动画的开始、结束、被取消、重复等事件~但是有时候会觉得,我只要知道结束就行了,这么长的代码我不能接收,那你可以使用AnimatorListenerAdapter
[java]  view plain  copy
  1. anim.addListener(new AnimatorListenerAdapter()  
  2. {  
  3.     @Override  
  4.     public void onAnimationEnd(Animator animation)  
  5.     {  
  6.         Log.e(TAG, "onAnimationEnd");  
  7.         ViewGroup parent = (ViewGroup) mBlueBall.getParent();  
  8.         if (parent != null)  
  9.             parent.removeView(mBlueBall);  
  10.     }  
  11. });  

AnimatorListenerAdapter继承了AnimatorListener接口,然后空实现了所有的方法~


AnimatorSet的使用:

对于一个属性同时作用多个属性动画效果,前面已经用PropertyValuesHolder 实现了这样的效果。而AnimatorSet 不仅能实现这样的效果,同时也能实现更为精确的顺序控制。

eg:

ObjectAnimator a1 = ObjectAnimator.ofFloat(view , "translationX" , 300f);
ObjectAnimator a2 = ObjectAnimator.ofFloat(view , "scaleX" , 1f , 0f , 1f);
ObjectAnimator a3 = ObjectAnimator.ofFloat(view , "scaleY" , 1f , 0f , 1f);
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(a1 , a2 , a3);
set.start();

在属性动画中,AnimatorSet正是通过playTogether() , playSequentially() , animSet.play().with() . before() , after()这些方法的来控制多个动画的协同工作方式,从而做到对动画播放顺序的精确控制。

1、如何使用xml文件来创建属性动画

大家肯定都清楚,View Animator 、Drawable Animator都可以在anim文件夹下创建动画,然后在程序中使用,甚至在Theme中设置为属性值。当然了,属性动画其实也可以在文件中声明:

首先在res下建立animator文件夹,然后建立res/animator/scalex.xml

[html]  view plain  copy
  1. xml version="1.0" encoding="utf-8"?>  
  2. <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:duration="1000"  
  4.     android:propertyName="scaleX"  
  5.     android:valueFrom="1.0"  
  6.     android:valueTo="2.0"  
  7.     android:valueType="floatType" >  
  8. objectAnimator>  
代码:
[java]  view plain  copy
  1. public void scaleX(View view)  
  2.     {  
  3.         // 加载动画  
  4.         Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);  
  5.         anim.setTarget(mMv);  
  6.         anim.start();  
  7.     }  

如果我希望纵向与横向同时缩放呢?则可以怎么定义属性文件:

[html]  view plain  copy
  1. xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:ordering="together" >  
  4.   
  5.     <objectAnimator  
  6.         android:duration="1000"  
  7.         android:propertyName="scaleX"  
  8.         android:valueFrom="1"  
  9.         android:valueTo="0.5" >  
  10.     objectAnimator>  
  11.     <objectAnimator  
  12.         android:duration="1000"  
  13.         android:propertyName="scaleY"  
  14.         android:valueFrom="1"  
  15.         android:valueTo="0.5" >  
  16.     objectAnimator>  
  17.   
  18. set>  

使用set标签,有一个orderring属性设置为together,【还有另一个值:sequentially(表示一个接一个执行)】。

另外缩放、反转等都有中心点或者轴,默认中心缩放,和中间对称线为反转线,所以我决定这个横向,纵向缩小以左上角为中心点:

代码:

[java]  view plain  copy
  1. // 加载动画  
  2.         Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);  
  3. //设置中心只能在代码中设置了
  4.         mMv.setPivotX(0);  
  5.         mMv.setPivotY(0);  
  6.         //显示的调用invalidate  
  7.         mMv.invalidate();  
  8.         anim.setTarget(mMv);  
  9.         anim.start();  




你可能感兴趣的:(Android)