本文是对Android动画的汇总关于Android的动画包括 3.0之前的View Animation,3.0之后的 Property Animator 以及5.0新增的(Touch feedback(触摸反馈)Reveal effect(揭露效果)Activity transitions(Activity转换效果)Curved motion(曲线运动)View state changes (视图状态改变)Animate Vector Drawables(可绘矢量动画))6种动画。


几种动画的详细内容如下:

  1. View Animation :

     第一类是Tween动画,就是对场景里的对象不断的进行图像变化来产生动画效果。 

       第二类就是 Frame动画,即顺序的播放事先做好的图像,与gif图片原理类似。


       下面就讲一下Tweene Animations。

        主要类:

          Animation   动画

          AlphaAnimation 渐变透明度

          otateAnimation 画面旋转

          ScaleAnimation 渐变尺寸缩放

          ranslateAnimation 位置移动

          AnimationSet  动画集


      以自定义View为例,该View很简单,画面上只有一个图片。 现在我们要对整个View分别实现各种Tween动画效果。 

      1) AlphaAnimation实现代码:  

      //初始化        Animation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);        //设置动画时间                 alphaAnimation.setDuration(3000);        this.startAnimation(alphaAnimation);


        其中AlphaAnimation类第一个参数fromAlpha表示动画起始时的透明度, 第二个参数toAlpha表示动画结束时的透明度。setDuration用来设置动画持续时间。

       fromAlpha、toAlpha属性说明:0.0表示完全透明 1.0表示完全不透明 以上值取0.0-1.0之间的float数据类型的数字

    

      2) RotateAnimation实现代码:

      Animation rotateAnimation = new RotateAnimation(0f, 360f);        rotateAnimation.setDuration(1000);        this.startAnimation(rotateAnimation);


      其中RotateAnimation类第一个参数fromDegrees表示动画起始时的角度, 第二个参数toDegrees表示动画结束时的角度。另外还可以设置伸缩模式pivotXType、pivotYType, 伸缩动画相对于x,y 坐标的开始位置pivotXValue、pivotYValue等        fromDegrees、toDegrees属性值说明0.0表示收缩到没有 1.0表示正常无伸缩 值小于1.0表示收缩 值大于1.0表示放大。 

                              当角度为负数——表示逆时针旋转
                              当角度为正数——表示顺时针旋转
                              (负数from——to正数:顺时针旋转)
                              (负数from——to负数:逆时针旋转)
                              (正数from——to正数:顺时针旋转)
                              (正数from——to负数:逆时针旋转)

        pivotX、pivotY属性值说明:从0%-100%中取值,50%为物件的X或Y方向坐标上的中点位置


      3) ScaleAnimation实现代码:

       //初始化          Animation scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f);         //设置动画时间         scaleAnimation.setDuration(500);         this.startAnimation(scaleAnimation);

 

      ScaleAnimation类中

      第一个参数fromX ,第二个参数toX:分别是动画起始、结束时X坐标上的伸缩尺寸。

      第三个参数fromY ,第四个参数toY:分别是动画起始、结束时Y坐标上的伸缩尺寸。

      另外还可以设置伸缩模式pivotXType、pivotYType, 伸缩动画相对于x,y 坐标的开始位置pivotXValue、pivotYValue等。

     

     4)TranslateAnimation实现代码:

       //初始化         nimation translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f);         //设置动画时间                       translateAnimation.setDuration(1000);         this.startAnimation(translateAnimation);

   

     TranslateAnimation类 

     第一个参数fromXDelta ,第二个参数toXDelta:分别是动画起始、结束时X坐标。

    第三个参数fromYDelta ,第四个参数toYDelta:分别是动画起始、结束时Y坐标。


      5)AnimationSet实现代码:


            //初始化 Translate动画          translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f);          //初始化 Alpha动画          alphaAnimation = new AlphaAnimation(0.1f, 1.0f);                //动画集          AnimationSet set = new AnimationSet(true);           set.addAnimation(translateAnimation);          set.addAnimation(alphaAnimation);                //设置动画时间 (作用到每个动画)          set.setDuration(1000);          this.startAnimation(set);

   

      6)Interpolator

       用于修改一个动画过程中的速率,可以定义各种各样的非线性变化函数,比如加速、减速等。

       在Android中所有的插值器都是Interpolator 的子类,通过 android:interpolator 属性你可以引用不同的插值器。下面是几种插值

       你可以通过下面的方式使用它们:

                     


       自定义插值器

       如果你对系统提供的插值器不满意,我们可以创建一个插值器资源修改插值器的属性,比如修改AnticipateInterpolator的加速速率,调整CycleInterpolator的循环次数等。为了完成这种需求,我们需要创建XML资源文件,然后将其放于/res/anim下,然后再动画元素中引用即可。我们先来看一下几种常见的插值器可调整的属性:

       <?xml version="1.0" encoding="utf-8"?>
                   android:attribute_name="value"
         />

    

       android:factor 浮点值,加速速率,默认为1

       android:tension 浮点值,起始点后退的张力、拉力数,默认为2

       android:tension 同上 android:extraTension 浮点值,拉力的倍数,默认为1.5(2 * 1.5)

       android:cycles int,循环的个数,默认为1

       android:factor 浮点值,减速的速率,默认为1

       浮点值,超出终点后的张力、拉力,默认为2


       比如:res/anim/my_overshoot_interpolator.xml:

      <?xml version="1.0" encoding="utf-8"?>
        android:tension="7.0"/>

    This animation XML will apply the interpolator:


                  android:interpolator="@anim/my_overshoot_interpolator"
        android:fromXScale="1.0"
        android:toXScale="3.0"
        android:fromYScale="1.0"
        android:toYScale="3.0
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="700" />

    如果简单的修改插值器的属性值还不能够满足我们的需求,那么就自己来通过实现Interpolator接口来定义自己的插值器了因为上面所有的Interpolator都实现了Interpolator接口,这个接口定义了一个方法:float getInterpolation(float input);此方法由系统调用,input代表动画的时间,在0和1之间,也就是开始和结束之间。


    线性(匀速)插值器定义如下:

       

             public float getInterpolation(float input) {              return input;          }

    加速减速插值器定义如下:

            public float getInterpolation(float input) {          return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;          }



   2.PropertyAnimator动画

  Property Animation动画有两个步聚:
    a.计算属性值
    b.为目标对象的属性设置属性值,即应用和刷新动画

    1) 计算属性值

     过程一:计算已完成动画分数 elapsed fraction
   为了执行一个动画,你需要创建一个ValueAnimator,并且指定目标对象属性的开始、结束值和持续时间。在调用start后的整个动画过程中, ValueAnimator会根据已经完成的动画时间计算得到一个0到1之间的分数,代表该动画的已完成动画百分比。0表示0%,1表示100%。

       过程二:计算插值(动画变化率)interpolated fraction
当ValueAnimator计算完已完成动画分数后,它会调用当前设置的TimeInterpolator,去计算得到一个interpolated(插值)分数,在计算过程中,已完成动画百分比会被加入到新的插值计算中。

       过程三:计算属性值
当插值分数计算完成后,ValueAnimator 会根据插值分数调用合适的 TypeEvaluator去计算运动中的属性值。
以上分析引入了两个概念:已完成动画分数(elapsed fraction)、插值分数( interpolated fraction
)。

    核心类:

     


    a. Evaluators

    Evaluators 告诉属性动画系统如何去计算一个属性值。它们通过Animator提供的动画的起始和结束值去计算一个动画的属性值。

    属性系统提供了以下几种Evaluators:

     1.IntEvaluator

     2.FloatEvaluator

     3.ArgbEvaluator

     这三个由系统提供,分别用于计算int,float,color型(十六进制)属性的计算器


    b.TypeEvaluator

    一个用于用户自定义计算器的接口,如果你的对象属性值类型,不是int,float,或者color类型,你必须实现这个接口,去定义自己的数据类型。TypeEvaluator接口只有一个方法,就是evaluate()方法,它允许你使用的animator返回一个当前动画点的属性值。

   c.ValueAnimator

   属性动画中的主要的时序引擎,如动画时间,开始、结束属性值,相应时间属性值计算方法等。包含了所有计算动画值的核心函数。也包含了每一个动画时间上的细节,信息,一个动画是否重复,是否监听更新事件等,并且还可以设置自定义的计算类型。

   使用ValueAnimator实现动画需要手动更新:


ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);animation.setDuration(1000);animation.addUpdateListener(new AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {Log.i("update", ((Float) animation.getAnimatedValue()).toString());}});animation.setInterpolator(new CycleInterpolator(3));animation.start();


   d.ObjectAnimator

   继承自ValueAnimator,允许你指定要进行动画的对象以及该对象的一个属性。该类会根据计算得到的新值自动更新属性。ObjectAnimator的自动更新功能,依赖于属性身上的setter和getter方法,所以为了让ObjectAnimator能够正确的更新属性值,你必须遵从以下规范:

1. 该对象的属性必须有get和set方法(方法的格式必须是驼峰式),方法格式为set(),因为ObjectAnimator会自动更新属性,它必须能够访问到属性的setter方法,比如属性名为foo,你就需要一个setFoo()方法,如果setter方法不存在,你有三种选择:

a.添加setter方法

b.使用包装类。通过该包装类通过一个有效的setter方法获取或者改变属性值的方法,然后应用于原始对象,比如NOA的AnimatorProxy。

c.使用ValueAnimator代替

(这3点的意思总结起来就是一定要有一个setter方法,让ObjectAnimator能够访问到)

 

如果你为ObjectAnimator的工厂方法的可变参数只传递了一个值,那么会被作为动画的结束值。


   e. AnimatorSet

   提供组合动画能力的类。并可设置组中动画的时序关系,如同时播放、有序播放或延迟播放。Elevator会告诉属性动画系统如何计算一个属性的值,它们会从Animator类中获取时序数据,比如开始和结束值,并依据这些数据计算动画的属性值。


   f.ViewPropertyAnimator

   可以方便的为某个View的多个属性添加并行的动画,只使用一个ViewPropertyAnimator对象就可以完成。它的行为更像一个ObjectAnimator,因为它修改的是对象的实际属性值。但它为一次性给多个属性添加动画提供了方便,而且使用ViewPropertyAnimator的代码更连贯更易读。

下面的代码段分别展示了使用多个ObjectAnimator对象、一个ObjectAnimator对象、 ViewPropertyAnimator同时为一个View的X和Y属性添加动画的示例:

多个ObjectAnimator结合AnimatorSet实现


ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);AnimatorSet animSetXY = new AnimatorSet();animSetXY.playTogether(animX, animY);animSetXY.start();


一个ObjectAnimator结合多个PropertyValuesHolder实现

ropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();

ViewPropertyAnimator: 只需一行代码

myView.animate().x(50f).y(100f);//myView.animate()直接返回一个ViewPropertyAnimator对象

   g.PropertyValuesHolder

   顾名思义,该类持有属性,相关属性值的操作以及属性的setter,getter方法的创建,属性值以Keyframe来承载,最终由KeyframeSet统一处理。


   h.KeyFrame

   一个keyframe对象由一对 time / value的键值对组成,可以为动画定义某一特定时间的特定状态。每个keyframe可以拥有自己的插值器,用于控制前一帧和当前帧的时间间隔间内的动画。

Keyframe.ofFloat(0f,0f);

第一个参数为:要执行该帧动画的时间节点(elapsed time / duration)

第二个参数为属性值。

    因此如果你想指定某一特定时间的特定状态,那么简单的使用ObjectAnimator就满足不了你了,因为ObjectAnimator.ofInt(....)类似的工厂方法,无法指定特定的时间点的状态。

    每个KeyFrame其实也有个Interpolator。如果没有设置,默认是线性的。之前为Animator设置的Interpolator是整个动画的,而系统允许你为每一KeyFrame的单独定义Interpolator,系统这样做的目的是允许你在某一个keyFrame做特殊的处理,也就是整体上是按照你的插值函数来计算,但是,如果你希望某个或某些KeyFrame会有不同的动画表现,那么你可以为这个keyFrame设置Interpolator。因此,Keyframe的定制性更高,你如果想精确控制某一个时间点的动画值及其运动规律,你可以自己创建特定的Keyframe 。


Keyframe使用

为了实例化一个keyframe对象,你必须使用某一个工厂方法:ofInt(), ofFloat(), or ofObject() 去获取合适的keyframe类型,然后你调用ofKeyframe工厂方法去获取一个PropertyValuesHolder对象,一旦你拥有了该对象,你可以将PropertyValuesHolder作为参数获取一个Animator,如下:


Keyframe kf0 = Keyframe.ofFloat(0f, 0f);Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);Keyframe kf2 = Keyframe.ofFloat(1f, 0f);PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);//动画属性名,可变参数ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)rotationAnim.setDuration(5000);

   i. KeyFrameSet


   根据Animator传入的值,为当前动画创建一个特定类型的KeyFrame集合。

通常通过ObjectAnimator.ofFloat(…)进行赋值时,这些值其实是通过一个KeyFrameSet来维护的

比如:

ObjectAnimator.ofFloat(target, "translateX", 50, 100, 200);

调用者传入的values 为 50,100,200,则numKeyframs = 3,那么创建出相应的Keyframe为:

Keyframe(0,50),Keyframe(1/2,100),Keyframe(1,200), 时间点 0,1/2,1 都是按比例划分的


public static KeyframeSet ofFloat(float... values) {int numKeyframes = values.length;FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)];if (numKeyframes == 1) {keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f);keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]);} else {keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]);for (int i = 1; i < numKeyframes; ++i) {keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);//这里是关键}}return new FloatKeyframeSet(keyframes);


  2) 在XML中声明属性动画

   通过在XML中定义的动画,可以很方便的在多个Activities中重用而且更容易编辑,复用性强。为了区分新的属性动画,从3.1开始,你应res/animator/下存放属性动画的资源文件,使用animator文件夹是可选的,但是如果你想在Eclipse ADT插件中使用布局编辑工具(ADT 11.0.0+),就必须在res/animator文件夹下存放了,因为ADT只会查找res/animator文件夹下的属性动画资源文件。


属性动画支持的Tag有

ValueAnimator -

ObjectAnimator -

AnimatorSet -



AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,R.anim.property_animator);set.setTarget(myObject);set.start();


目录res/animator/filename.xm


编译后的资源为ValueAnimator, ObjectAnimator, or AnimatorSet


XML文件的根元素必须为,, or 之一。也可以在一个set中组织不同的动画,包含其它元素,也就是说,可以嵌套。


        ...    


  3.Andriod L的动画

     Material Design是Google推出的一个全新的设计语言,它的特点就是拟物扁平化。     

     在Android L中新增了如下几种动画:

      a. Touch feedback(触摸反馈)

      b. Reveal effect(揭露效果)

      c. Activity transitions(Activity转换效果)

      d. Curved motion(曲线运动)

      e. View state changes (视图状态改变)

      f. Animate Vector Drawables(可绘矢量动画)


 详细的内容如下:

    1. 触摸反馈:

    触摸反馈最具代表性的就是波纹动画,比如当点击按钮时会从点击的位置产生类似于波纹的扩散效果。

    1)波纹效果(Ripple):

     可以通过如下代码设置波纹的背景:android:background="?android:attr/selectableItemBackground"波纹有边界  android:background="?android:attr/selectableItemBackgroundBorderless"波纹超出边界


具体代码如下:

        

效果如下:

    2)设置颜色

     我们也可以通过设置xml属性来调节动画颜色,从而可以适应不同的主题:

      android:colorControlHighlight:设置波纹颜色 

     android:colorAccent:设置checkbox等控件的选中颜色


   2. Circular Reveal:

   使用方法:

   应用ViewAnimationUtils.createCircularReveal()方法可以去创建一个RevealAnimator动画 。

   ViewAnimationUtils.createCircularReveal源码如下:

 public static Animator createCircularReveal(View view,nt centerX,  int centerY, float startRadius, float endRadius) {    return new RevealAnimator(view, centerX, centerY, startRadius, endRadius);   }

源码非常简单,就是通过createCircularReveal方法根据5个参数来创建一个RevealAnimator动画对象。


这五个参数分别是:

view 操作的视图

  centerX 动画开始的中心点X

  centerY 动画开始的中心点Y

  startRadius 动画开始半径

  startRadius 动画结束半径


实例代码:

final View oval = this.findViewById(R.id.oval);      oval.setOnClickListener(new View.OnClickListener() {          @Override          public void onClick(View v) {              Animator animator = ViewAnimationUtils.createCircularReveal(                      oval,oval.getWidth()/2,oval.getHeight()/2,oval.getWidth(),0);              animator.setInterpolator(new AccelerateDecelerateInterpolator());              animator.setDuration(2000);              animator.start();          }      });        final View rect = this.findViewById(R.id.rect);        rect.setOnClickListener(new View.OnClickListener() {          @Override          public void onClick(View v) {              Animator animator = ViewAnimationUtils.createCircularReveal(                      rect,0,0,0,(float) Math.hypot(rect.getWidth(), rect.getHeight()));              animator.setInterpolator(new AccelerateInterpolator());              animator.setDuration(2000);              animator.start();          }  });

显示效果:

 



 3. Activity Transition


   1) 什么是Transition?

   安卓5.0中Activity和Fragment 变换是建立在名叫Transitions的安卓新特性之上的。这个诞生于4.4的transition框架为在不同的UI状态之间产生动画效果提供了非常方便的API。该框架主要基于两个概念:场景(scenes)和变换(transitions)。场景(scenes)定义了当前的UI状态,变换(transitions)则定义了在不同场景之间动画变化的过程。虽然transition翻译为变换似乎很确切,但是总觉得还是没有直接使用transition直观,为了更好的理解下面个别地方直接用transition代表变换。


   当一个场景改变的时候,transition主要负责:

  (1)捕捉每个View在开始场景和结束场景时的状态。

  (2)根据两个场景(开始和结束)之间的区别创建一个Animator。


   2) Android 5.0(API 级别 21)支持这些进入与退出转换:

     (1)分解 - 从场景中心移入或移出视图。

     (2)滑动 - 从场景边缘移入或移出视图。

     (3)淡入淡出 - 通过调整透明度在场景中增添或移除视图。


   3)Android 5.0(API 级别 21)也支持这些共享元素转换:

     (1)changeBounds - 为目标视图的布局边界的变化添加动画。

     (2) changeClipBounds - 为目标视图的裁剪边界的变化添加动画。

     (3)changeTransform - 为目标视图的缩放与旋转变化添加动画。

     (4)changeImageTransform - 为目标图像的大小与缩放变化添加动画。


   4) 实现方式:

     (1). xml 实现方式:

      res/transition/activity_fade.xml

<?xml version="1.0" encoding="utf-8"?>res/transition/activity_slide.xml<?xml version="1.0" encoding="utf-8"?>

    MainActivity.java

    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_transition);        setupWindowAnimations();    }     private void setupWindowAnimations() {Slide slide = TransitionInflater.from(this).inflateTransition(R.transition.activity_slide);getWindow().setExitTransition(slide);}@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_transition);        setupWindowAnimations();}private void setupWindowAnimations() {        Fade fade = TransitionInflater.from(this).inflateTransition(R.transition.activity_fade);        getWindow().setEnterTransition(fade);    }

 

    (2)代码实现方式:

     MainActivity.java

 @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_transition);        setupWindowAnimations();    }    private void setupWindowAnimations() {        Slide slide = new Slide();        slide.setDuration(1000);        getWindow().setExitTransition(slide);    }

     TransitionActivity.java

    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_transition);        setupWindowAnimations();    }     private void setupWindowAnimations() {        Fade fade = new Fade();        fade.setDuration(1000);        getWindow().setEnterTransition(fade);    }


实例代码:


   (1). Styles文件 :

              @color/colorPrimary        @color/colorPrimaryDark        @color/colorAccent                 true                false        false    



   (2). MainActivity部分代码:

 @Override    public void onClick(View v) {        ArrayList> arrayList = new ArrayList>();        switch (v.getId()) {            case R.id.explode_btn:                setExplodeTransition();                flag = AnimConstant.EXPLODE_FLAG;                break;            case R.id.slide_btn:                setSlideTransition();                flag = AnimConstant.SLIDE_FLAG;                break;            case R.id.pade_in_out_btn:                setFadeTransition();                flag = AnimConstant.PADE_IN_OUT_FLAG;                break;            case R.id.shared_element_btn:                arrayList.add(new Pair(shareElementBtn, "shared_name_btn"));                flag = AnimConstant.SHARED_ELEMENTS_FLAG;                break;        }        startActivity(arrayList);    }    private void setFadeTransition() {        Fade fadeTransition = new Fade();        fadeTransition.setDuration(1000);        getWindow().setReenterTransition(fadeTransition);        getWindow().setExitTransition(fadeTransition);    }     private void startActivity(ArrayList> arrayList) {        Intent intent = new Intent();        intent.setClass(this ,SecondActivity.class);        intent.putExtra("transition_flag",flag);        ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, arrayList.toArray(new Pair[arrayList.size()]));        startActivity(intent, options.toBundle());    }   private void setExplodeTransition() {        Explode explode = new Explode();        explode.setDuration(2000);        getWindow().setReenterTransition(explode);        getWindow().setExitTransition(explode);    }    private void setSlideTransition() {        Slide slideTransition = new Slide();        slideTransition.setSlideEdge(Gravity.LEFT);        slideTransition.setDuration(1000);        getWindow().setReenterTransition(slideTransition);        getWindow().setExitTransition(slideTransition);}

  (3) SecondActivity类:

  private Button returnBtn = null;     @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_second);        Intent intent = getIntent();        int flag = intent.getIntExtra("transition_flag" ,-1);        if (flag != AnimConstant.SHARED_ELEMENTS_FLAG) {            setupWindowAnimations();        }        returnBtn = (Button) this.findViewById(R.id.return_btn);        returnBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                finishAfterTransition();            }        });    }     private void setupWindowAnimations() {        Explode explode = new Explode();        explode.setDuration(2000);        getWindow().setEnterTransition(explode);    }

显示效果:

   4.Curved motion

              Material design中的动画利用曲线实现时间内插与空间移动模式。 在 Android 5.0API 级别 21)及更高版本,您可为动画定义定制时间曲线以及曲线运动模式。PathInterpolator 类别是一个基于贝塞尔曲线或 Path 对象的全新插入器。 此插入器在一个 1x1 的正方形内指定一个运动曲线,定位点位于 (0,0) 以及 (1,1),而控制点则使用构造函数参数指定。 

有两种定义PathInterpolator的方法:

 第一种XML方式:


系统将为材料设计规范中的三种基本曲线提供 XML 资源:

@interpolator/fast_out_linear_in.xml

@interpolator/fast_out_slow_in.xml

@interpolator/linear_out_slow_in.xml


第二种代码实现

public class SCPahtInterpolator extends PathInterpolator {    public static final float DEFALUT_CONTROL_1_X = 0.5f;    public static final float DEFALUT_CONTROL_1_Y = 0f;    public static final float DEFALUT_CONTROL_2_X = 0f;    public static final float DEFALUT_CONTROL_2_Y = 1f;    public SCPahtInterpolator() {        super(DEFALUT_CONTROL_1_X, DEFALUT_CONTROL_1_Y, DEFALUT_CONTROL_2_X, DEFALUT_CONTROL_2_Y);    }    public SCPahtInterpolator(Path path) {        super(path);    }    public SCPahtInterpolator(float controlX, float controlY) {        super(controlX, controlY);    }    public SCPahtInterpolator(float controlX1, float controlY1, float controlX2, float controlY2) {        super(controlX1, controlY1, controlX2, controlY2);    }    public SCPahtInterpolator(Context context, AttributeSet attrs) {        super(context, attrs);    }}

可用Animator.setInterpolator()设置PathInterpolator

ObjectAnimator 类别拥有新的构造函数,可让您一次使用两个或更多属性在路径上为坐标添加动画。 例如,下列动画使用 Path 对象为视图的 X 和 Y 属性添加动画:

ObjectAnimator mAnimator;mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);...mAnimator.start();


   5.视图状态改变

   StateListAnimator 类别让您能够定义视图状态改变时运行的动画。 下列示例显示如何将 StateListAnimator 定义为一个 XML 资源:

                                            


如果要将定制视图状态动画附加至一个视图,请依照此示例使用 XML 资源文件中的 selector 元素定义一个动画,并使用 android:stateListAnimator属性将此动画分配给您的视图。 如果要将一个状态列表动画分配给您的代码内的一个视图,请使用 AnimationInflater.loadStateListAnimator() 方法,并以 View.setStateListAnimator() 方法将动画分配给您的视图。

当您的主题扩展材料主题时,在默认情况下按钮将拥有一个 Z 动画。如果要避免您的按钮出现这类行为,请将 android:stateListAnimator 属性设置为@null。

AnimatedStateListDrawable 类别让您能够创建图片,显示相关视图之间的状态变化。 Android 5.0 中的某些系统小组件在默认情况下使用这些动画。 下列示例显示如何将 AnimatedStateListDrawable 定义为一个 XML 资源:

                                                                      ...                ...


 

   6.为矢量图片添加动画

   矢量图片可在不丢失定义的情况下缩放。 AnimatedVectorDrawable 类别可让您为矢量图片的属性添加动画。

您通常可以在 3 个 XML 文件中定义添加动画的矢量图片:

在 res/drawable/ 中拥有 元素的矢量图片

在 res/drawable/ 中拥有 元素且已添加动画的矢量图片

在 res/anim/ 中拥有 元素的一个或多个对象动画

添加动画的矢量图片可为 以及 元素的属性添加动画。 元素定义路径集或子组,而 元素则定义将绘制的路径。

当您定义一个您想要添加动画的矢量图片时,请使用 android:name 属性给这些群组和路径指定一个唯一名称,以便让您能够从您的动画定义中引用这些群组或路径。 例如:

                

已添加动画的矢量图片定义按名称引用矢量图片内的群组和路径:

        


动画定义代表着 ObjectAnimator 或 AnimatorSet 对象。此示例中的第一个动画将目标群组旋转 360 度:


此示例中的第二个动画对矢量图片的路径进行变形。 两个路径均需可兼容变形操作:两个路径均需拥有相同数量的指令,而且每个指令均需拥有相同数量的参数。


    



引用的文章:

   http://www.open-open.com/lib/view/open1416663769680.html

   http://blog.csdn.net/feng88724/article/details/6318430

   http://www.lightskystreet.com/2015/05/23/anim_basic_knowledge/



  



更多相关文章

  1. 【Android(安卓)开发教程】自定义服务
  2. Android(安卓)解决自定义控件布局中match_parent属性无效
  3. Android自定义控件:Android(安卓)L控件点击水波纹的实现(源码 + De
  4. Task和Activity相关的一些属性
  5. Android(安卓)仿拼多多可水平滚动RecyclerView,自定义滚动条滚动
  6. Android动画开发之Animation动画效果
  7. Android中使用httpclient访问服务器,需要session功能
  8. 【Android】 Activity
  9. android中自定义checkbox的图片和大小

随机推荐

  1. linux中openssl和ssh的配置和简单应用
  2. linux python调试技巧
  3. LAMP兄弟连PHP全民总动员
  4. 如何解决Python.h:No such file or direct
  5. Python如何规避全局解释器锁(GIL)带来的
  6. python 画图--简单开始及折线图
  7. 贝叶斯学习 -- matlab、python代码分析(3)
  8. date时间加减(linux,aix)
  9. 萌妹子Python入门指北(四)
  10. 开发技术--Python核心知识A