全面讲解Android全套动画使用技巧

    作者:课课家教育更新于: 2017-05-11 19:02:23

         在几天前,跟朋友一起在讨论Android全套动画,但是他说的操作有点麻烦。今天,我就跟各位小伙伴说一下Android全套动画使用技巧,有需要的小伙伴,可以参考一下。文章里面有一些细节内容,还望小伙伴们认真阅读哦!

         一、AndroidView动画框架

      Animation框架定义了透明度、旋转、缩放和位移几种常见的动画,控制的整个View,实现原理是每次绘制视图时View所在ViewGroup中的drawChild函数获取该View的Animation的Transformation值,然后调用canvas.concat(transformToApply.getMatrix()),通过矩阵运算完成动画帧。如果没有完成就继续调用invalidate()函数,启动下次绘制来驱动动画,从而完成整个动画的绘制。

      视图动画使用简单,效果丰富,它提供了AlphaAnimation、RotateAnimation、TranslateAnimation、ScaleAnimation四种动画方式,并提供动画集合AnimationSet,混合使用多种动画。在Android3.0之前,视图动画一家独大,但随着Android3.0之后属性动画框架的推出,它的风光就大不如从前。相比属性动画,视图动画的一个非常大的缺陷就是不具备交互性,当某个元素发生视图动画后,其响应事件的位置还依然在动画前的地方,所以视图动画只能做普通的动画效果,避免交互的发生。但是它的优点也非常明显,即效率比较高且使用方便。

      视图动画使用非常简单,不仅可以通过XML文件来描述一个动画过程,同样也可以使用代码来控制整个动画过程。

      (1)、透明度动画

      为视图增加透明度的变换动画。

      AlphaAnimationaa=newAlphaAnimation(0,1);

      aa.setDuration(1000);

      view.startAnimation(aa);

      (2)、旋转动画

      为视图增加旋转的变换动画。

      RotateAnimationra=newRotateAnimation(0,360,100,100);

      ra.setDuration(1000);

      view.startAnimation(ra);

      其参数分别为旋转的起始角度和旋转中心点的坐标,当然,可以通过设置参数来控制旋转动画的参考系,这里设置旋转动画的参考系为中心。

      RotateAnimationra1=newRotateAnimation(0,360,RotateAnimation.RELATIVE_TO_SELF,0.5F,RotateAnimation.RELATIVE_TO_SELF,0.5F);

      (3)、位移动画

      为视图移动时增加位移动画。

      TranslateAnimationta=newTranslateAnimation(0,200,0,300);

      ta.setDuration(1000);

      view.startAnimation(ta);

      (4)、缩放动画

      为视图的缩放增加动画效果

      ScaleAnimationsa=newScaleAnimation(0,2,0,2);

      sa.setDuration(1000);

      view.startAnimation(sa);

      与旋转动画一样,缩放动画也可以设置罗芳的中心点,设置中心为自身中心效果

      ScaleAnimationsa1=newScaleAnimation(0,1,0,1,Animation.RELATIVE_TO_SELF,0.5F,Animation.RELATIVE_TO_SELF,0.5F);

      sa1.setDuration(1000);

      view.startAnimation(sa1);

      (5)、动画集合

      通过AnimationSet,可以将动画以组合的形式展现出来:

      AnimationSetas=newAnimationSet(true);

      as.setDuration(1000);

      AlphaAnimationaa=newAlphaAnimation(0,1);

      aa.setDuration(1000);

      as.addAnimation(aa);

      RotateAnimationra=newRotateAnimation(0,360,100,100);

      ra.setDuration(1000);

      as.addAnimation(ra);

      TranslateAnimationta=newTranslateAnimation(0,200,0,300);

      ta.setDuration(1000);

      as.addAnimation(ta);

      ScaleAnimationsa=newScaleAnimation(0,2,0,2);

      sa.setDuration(1000);

      as.addAnimation(sa);

      view.startAnimation(as);

      可以直接拷贝运行代码看效果!

      对于动画事件,Android也提供了对应的监听回调,代码:

      as.setAnimationListener(newAnimation.AnimationListener(){

      @Override

      publicvoidonAnimationStart(Animationanimation){

      //动画开始

      }

      @Override

      publicvoidonAnimationEnd(Animationanimation){

      //动画结束

      }

      @Override

      publicvoidonAnimationRepeat(Animationanimation){

      //动画重复

      }

      });

      二、属性动画

    全面讲解Android全套动画使用技巧_应用平台_java_课课家教育

      由于Android3.0之前已有的动画框架Animation存在一些局限性——动画改变的只是显示,并不能响应事件。因此在Android3.0之后,Google就提出了属性动画这样一个新的动画框架,实现更丰富的效果。

      而在Animator框架中使用最多的就是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator进行更精细化控制,只控制一个对象的一个属性值,而使用多个ObjectAnimator组合到AnimatorSet形成一个动画。而且ObjectAnimator能够自动驱动,可以调用setFrameDelay(longframeDelay)设置动画帧之间的间隙时间。最重要的是,属性动画通过调用属性的get、set方法来真实地控制了一个View的属性值,因此强大的属性动画框架,基本可以实现所有的动画效果。

      (1)、ObjectAnimator

      ObjectAnimator是属性动画框架中最重要的实行类,创建一个ObjectAnimator只需要通过他的静态工厂类直接返回一个ObjectAnimator对象。参数包括一个对象和对象的属性名字,但这个属性也必须有get和set函数,内部会通过反射机制来调用set函数修改对象属性值。同样,你也可以调用setInterpolator设置相应的差值器。

      接下来试想一下对一个Button添加一个平移动画,使用以前的动画框架平移后将不能触发点击事件,点击的有效区域仍然是原来的地方,点击移动后的地方是不会有点击事件发生的。而属性动画则不同,它真实地改变了一个View的属性,所以事件响应的区域也同样发生了改变,这时候点击移动后的按钮,就会响应点击事件了。

      属性动画平移代码如下:

      ObjectAnimatoranimator=ObjectAnimator.ofFloat(

      imageView,

      "translationX",

      200F);

      animator.setDuration(300);

      animator.start();

      在使用ObjectAnimator的时候,有一点非常重要,那就是要操纵的属性必须具有get、set方法,不然ObjectAnimator就无法生效。下面是常用的属性:

      translationX和translationY:这两个属性作为一种增量控制着View对象从它布局容器左上角坐标开始的位置。

      rotation、rotationX和rotationY:这个三个属性控制View对象围绕支点进行2D和3D旋转。

      scaleX和scaleY:这两个属性控制着View对象围绕他的支点进行2D缩放。

      pivotX和pivotY:这两个属性控制着View对象的支点位置,围绕这个支点进行旋转和缩放变换处理。默认情况下,该支点的位置就是View对象的中心点。

      x和y:这两个简单实用的属性,描述了View对象在它的容器中的最终位置,它是最初的左上角坐标和translationX、translationY值的累积和。

      alpha:表示View对象的alpha透明度。默认值是1(不透明),0代表完全透明(不可见)。

      根据以上得知视图动画所实现的动画效果,这里基本都已经包含了。

      那么如果一个属性没有get、set方法,属性动画是不是就束手无策了呢?答案是否定的,Google在应用层提供了两种方案来解决这个问题,一个是通过自定义一个属性类或者包装类,来间接地给这个属性增加get、set方法;或者通过ValueAnimator来实现,ValueAnimator在后面的内容中讲到,这个先看看使用包装类的方法给一个属性增加get、set方法,代码如下:

      privatestaticclassWrapperView{

      privateViewmTarget;

      publicWrapperView(ViewmTarget){

      this.mTarget=mTarget;

      }

      publicintgetWidth(){

      returnmTarget.getLayoutParams().width;

      }

      publicvoidsetWidth(intwidth){

      mTarget.getLayoutParams().width=width;

      mTarget.requestLayout();

      }

      }

      Android系统架构

      Android的系统架构和其操作系统一样,采用了分层的架构。

      Android结构

      Android结构

      从架构图看,Android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层。

      应用程序

      Android会同一系列核心应用程序包一起发布,该应用程序包包括客户端,SMS短消息程序,日历,地图,浏览器,联系人管理程序等。所有的应用程序都是使用java语言编写的。

      应用程序框架

      开发人员也可以完全访问核心应用程序所使用的API框架。该应用程序的架构设计简化了组件的重用;任何一个应用程序都可以发布它的功能块并且任何其它的应用程序都可以使用其所发布的功能块(不过得遵循框架的安全性)。同样,该应用程序重用机制也使用户可以方便的替换程序组件。

      隐藏在每个应用后面的是一系列的服务和系统,其中包括;

      丰富而又可扩展的视图(Views),可以用来构建应用程序,它包括列表(Lists),网格(Grids),文本框(Textboxes),按钮(Buttons),甚至可嵌入的web浏览器。

      内容提供器(ContentProviders)使得应用程序可以访问另一个应用程序的数据(如联系人数据库),或者共享它们自己的数据

      资源管理器(ResourceManager)提供非代码资源的访问,如本地字符串,图形,和布局文件(Layoutfiles)。

      通知管理器(NotificationManager)使得应用程序可以在状态栏中显示自定义的提示信息。

      活动管理器(ActivityManager)用来管理应用程序生命周期并提供常用的导航回退功能。

      系统运行库

      Android包含一些C/C++库,这些库能被Android系统中不同的组件使用。它们通过Android应用程序框架为开发者提供服务。以下是一些核心库:

      *系统C库-一个从BSD继承来的标准C系统函数库Libc),它是专门为基于Embeddedlinux的设备定制的。

      *媒体库-基于PacketVideoOpenCORE;该库支持多种常用的音频、视频格式回放和录制,同时支持静态图像文件。编码格式包括MPEG4,H.264,MP3,AAC,AMR,JPG,PNG。

      *SurfaceManager-对显示子系统的管理,并且为多个应用程序提供了2D和3D图层的无缝融合。

      *LibWebCore-一个最新的web浏览器引擎用,支持Android浏览器和一个可嵌入的web视图。

      通过以上代码,就跟一个属性包装了一层,并给它提供了get、set方法。使用时只需要操纵包装类就可以间接调用到get、set方法了,代码如下所示:

      WrapperViewwrapperView=newWrapperView(view);

      ObjectAnimator.ofInt(wrapperView,"width",500).setDuration(5000).start();

      (2)、PropertyValuesHolder

    类似视图动画中的AnimationSet,在属性动画中,如果针对同一个对象的多个属性,要同时作用多种动画,可以使用PropertyValuesHolder来实现。比如平移动画,如果在平移的过程中同时改变X、Y轴的缩放,可以这样实现,代码:

      类似视图动画中的AnimationSet,在属性动画中,如果针对同一个对象的多个属性,要同时作用多种动画,可以使用PropertyValuesHolder来实现。比如平移动画,如果在平移的过程中同时改变X、Y轴的缩放,可以这样实现,代码:

      PropertyValuesHolderpvh1=PropertyValuesHolder.ofFloat("translationX",300);

      PropertyValuesHolderpvh2=PropertyValuesHolder.ofFloat("scaleX",1f,0,1f);

      PropertyValuesHolderpvh3=PropertyValuesHolder.ofFloat("scaleY",1f,0,1f);

      ObjectAnimator.ofPropertyValuesHolder(pvh1,pvh2,pvh3).setDuration(1000).start();

      在代码中,分别使用PropertyValuesHolder对象控制translationX、scaleX、scaleY这三个属性,最屌调用ObjectAnimator.ofPropertyValuesHolder方法实现多属性动画的共同作用,整个实现方法非常类似AnimatorSet使用。

      (3)、ValueAnimator

    ValueAnimator在属性动画中占用非常重要的地位,虽然不ObjectAnimator那样耀眼,但它却是属性动画的核心所在,ObjectAnimator也是继承自ValueAnimator。

      ValueAnimator在属性动画中占用非常重要的地位,虽然不ObjectAnimator那样耀眼,但它却是属性动画的核心所在,ObjectAnimator也是继承自ValueAnimator。

      publicfinalclassObjectAnimatorextendsValueAnimator

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

      ValueAnimatorvalueAnimator=ValueAnimator.ofFloat(0,100);

      valueAnimator.setTarget(imageView);

      valueAnimator.setDuration(1000).start();

      valueAnimator.addUpdateListener(newValueAnimator.AnimatorUpdateListener(){

      @Override

      publicvoidonAnimationUpdate(ValueAnimatoranimation){

      Floatvalue=(Float)animation.getAnimatedValue();

      }

      });

      (4)、动画事件的监听

      一个完整的动画具有Start、Repeat、End、Cancel四个过程,通过Android提供了接口,很方便地监听到这四个事件:

      ObjectAnimatoranim=ObjectAnimator.ofFloat(imageView,"alpha",0.5F);

      anim.addListener(newAnimator.AnimatorListener(){

      @Override

      publicvoidonAnimationStart(Animatoranimation){

      }

      @Override

      publicvoidonAnimationEnd(Animatoranimation){

      }

      @Override

      publicvoidonAnimationCancel(Animatoranimation){

      }

      @Override

      publicvoidonAnimationRepeat(Animatoranimation){

      }

      });

      anim.start();

      大部分的时候只关心onAnimationEnd事件,所以Android也提供了一个AnimatorListenerAdapter来让我们选择必要的事件进行监听:

      anim.addListener(newAnimatorListenerAdapter(){

      @Override

      publicvoidonAnimationEnd(Animatoranimation){

      super.onAnimationEnd(animation);

      }

      });

      (5)、AnimatorSet

      对于一个属性同时作用多个属性动画效果,前面已经使用PropertyValuesHolder实现了这样的效果。而AnimatorSet不仅能实现这样的效果,同时也能实现更为精确的顺序控制。同样是实现上面使用PropertyValuesHolder演示的那个动画效果,如果使用AnimatorSet来实现,那么代码如下:

      ObjectAnimatorobjectAnimator=ObjectAnimator.ofFloat(imageView,"translationX",300f);

      ObjectAnimatorobjectAnimator1=ObjectAnimator.ofFloat(imageView,"scaleX",1f,0f,1f);

      ObjectAnimatorobjectAnimator2=ObjectAnimator.ofFloat(imageView,"scaleY",1f,0f,1f);

      AnimatorSetanimatorSet=newAnimatorSet();

      animatorSet.setDuration(1000);

      animatorSet.playTogether(objectAnimator,objectAnimator1,objectAnimator2);

      animatorSet.start();

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

      (6)、在XML中使用属性动画

      属性动画同视图动画一样,也可以直接写在XML文件中,代码:

      

      

      android:duration="1000"

      android:propertyName="scaleX"

      android:valueFrom="1.0"

      android:valueTo="2.0"

      android:valueType="floatType">

      

      前提使用XML定义属性动画XML文件一定要放在res/animator/filename.xml文件夹下面才能识别,否则不能识别。发现属性动画与视图动画在XML文件中的写法很相似。在程序中使用:

      Animatoranim=AnimatorInflater.loadAnimator(this,R.animator.filename);

      anim.setTarget(view);

      anim.start();

      (7)、View的animate方法

      在Android3.0之后,Google给View增加了animate方法来直接驱动属性动画,代码如下:

      imageView.animate()

      .alpha(0)

      .y(300)

      .setDuration(300)

      .withStartAction(newRunnable(){

      @Override

      publicvoidrun(){

      }

      })

      .withEndAction(newRunnable(){

      @Override

      publicvoidrun(){

      runOnUiThread(newRunnable(){

      @Override

      publicvoidrun(){

      }

      });

      }

      }).start();

      三、Android布局动画

      布局动画是指作用在ViewGroup上,给ViewGroup增加View时添加一个动画过渡效果。最简单的布局动画是在ViewGroup的XML中,使用如下代码打开布局动画:

      android:animateLayoutChanges="true"

      通过以上设置,当ViewGroup添加到View时,子View会呈现逐渐显示的过渡效果,不过这个效果是Android默认的显示的过渡效果,无法使用自定义动画来替换这个效果。

      还可以通过使用LayoutAnimatorController类自定义一个子View的过渡效果,添加一个视图动画,使得子View出现的时候有一个缩放的动画效果,代码:

      LinearLayoutll=(LinearLayout)findViewById(R.id.ll);

      ScaleAnimationsa=newScaleAnimation(0,1,0,1);

      sa.setDuration(2000);

      //设置布局动画的显示

      LayoutAnimationControllerlac=newLayoutAnimationController(sa,0.5f);

      //设置布局动画

      ll.setLayoutAnimation(lac);

      LayoutAnimationController的第一个参数,是需要作用的动画,而第二个参数,则是每个子View显示的delay时间。当delay时间不为0时,可以设置子View显示的顺序。

      //顺序

      publicstaticfinalintORDER_NORMAL=0;

      //随机

      publicstaticfinalintORDER_REVERSE=1;

      //反序

      publicstaticfinalintORDER_RANDOM=2;

      四、Interpolators——插值器

      插值器是动画一个非常重要的概念,通过插值器Interpolators,可以定义动画变换速率,这一点非常类似物理中的加速度,起作用主要是控制目标变量的变化值进行对应的变化。

      AccelerateDecelerateInterpolator在动画开始与介绍的地方速率改变比较慢,在中间的时候加速

      AccelerateInterpolator在动画开始的地方速率改变比较慢,然后开始加速

      AnticipateInterpolator开始的时候向后然后向前甩

      AnticipateOvershootInterpolator开始的时候向后然后向前甩一定值后返回最后的值

      BounceInterpolator动画结束的时候弹起

      CycleInterpolator动画循环播放特定的次数,速率改变沿着正弦曲线

      DecelerateInterpolator在动画开始的地方快然后慢

      LinearInterpolator以常量速率改变

      OvershootInterpolator向前甩一定值后再回到原来位置

      PathInterpolator路径插值器

         结束语:由于自己的时间紧迫,还有一些步骤说的不是很好。还望各位小伙伴谅解一下,如果各位小伙伴想了解更多这方面的知识,随时可以登陆课课家教育平台浏览,小编也会在最快的时间,写出更好的内容,也在课课家欢迎你随时浏览哦!

课课家教育

未登录