Android动画知识汇总

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android动画知识汇总相关的知识,希望对你有一定的参考价值。


   本文是对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 属性你可以引用不同的插值器。下面是几种插值

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

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


       自定义插值器

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

       <?xml version="1.0" encoding="utf-8"?>
           <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android"
        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"?>
    <overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:tension="7.0"/>

    This animation XML will apply the interpolator:


          <scale xmlns:android="http://schemas.android.com/apk/res/android"
        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() {
@Override
public 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 - <animator>

ObjectAnimator - <objectAnimator>

AnimatorSet - <set>


<set android:ordering="sequentially">
<set>
<objectAnimator
android:propertyName="x"
android:duration="500"
android:valueTo="400"
android:valueType="intType"/>
<objectAnimator
android:propertyName="y"
android:duration="500"
android:valueTo="300"
android:valueType="intType"/>
</set>
<objectAnimator
android:propertyName="alpha"
android:duration="500"
android:valueTo="1f"/>
</set>


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


目录res/animator/filename.xm


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


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


<set  
android:ordering=["together" | "sequentially"]>  
<objectAnimator  
android:propertyName="string"  
android:duration="int"  
android:valueFrom="float | int | color"  
android:valueTo="float | int | color"  
android:startOffset="int"  
android:repeatCount="int"  
android:repeatMode=["repeat" | "reverse"]  
android:valueType=["intType" | "floatType"]/>  
<animator  
android:duration="int"  
android:valueFrom="float | int | color"  
android:valueTo="float | int | color"  
android:startOffset="int"  
android:repeatCount="int"  
android:repeatMode=["repeat" | "reverse"]  
android:valueType=["intType" | "floatType"]/>  
<set>  
...  
</set>  
</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"波纹超出边界


具体代码如下:

<Button
        android:id="@+id/btn_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn_1"
        android:padding="10px"
        android:layout_below="@id/touch_feedback_ripple_textview"
        />
    <Button
        android:id="@+id/btn_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn_2"
        android:layout_below="@id/btn_1"
        android:padding="10px"
        android:background="?android:attr/selectableItemBackground"/>
    <Button
        android:id="@+id/btn_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn_3"
        android:layout_below="@id/btn_2"
        android:padding="10px"
      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"?>
<fade xmlns:android="http://schemas.android.com/apk/res/"
android:duration="1000"/>
res/transition/activity_slide.xml
<?xml version="1.0" encoding="utf-8"?>
<slide xmlns:android="http://schemas.android.com/apk/res/"
android:duration="1000"/>

    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文件 :

  <resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item> <!--设置选中的颜色-->
        <!-- 允许使用transitions -->
        <item name="android:windowContentTransitions">true</item>
        <!--是否覆盖执行,其实可以理解成是否同步执行还是顺序执行-->
        <item name="android:windowAllowEnterTransitionOverlap">false</item>
        <item name="android:windowAllowReturnTransitionOverlap">false</item>
    </style>
</resources>



   (2). MainActivity部分代码:

 @Override
    public void onClick(View v) {
        ArrayList<Pair<View,String>> arrayList = new ArrayList<Pair<View,String>>();
        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<View, String>(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<Pair<View, String>> 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方式:

<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:controlX1="0.4"
    android:controlY1="0"
    android:controlX2="1"
    android:controlY2="1"/>


系统将为材料设计规范中的三种基本曲线提供 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 资源:

<!-- animate the translationZ property of a view when pressed -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true">
    <set>
      <objectAnimator android:propertyName="translationZ"
        android:duration="@android:integer/config_shortAnimTime"
        android:valueTo="2dp"
        android:valueType="floatType"/>
        <!-- you could have other objectAnimator elements
             here for "x" and "y", or other properties -->
    </set>
  </item>
  <item android:state_enabled="true"
    android:state_pressed="false"
    android:state_focused="true">
    <set>
      <objectAnimator android:propertyName="translationZ"
        android:duration="100"
        android:valueTo="0"
        android:valueType="floatType"/>
    </set>
  </item>
</selector>


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

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

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

<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
    xmlns:android="http://schemas.android.com/apk/res/android">
 
    <!-- provide a different drawable for each state-->
    <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
        android:state_pressed="true"/>
    <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
        android:state_focused="true"/>
    <item android:id="@id/default"
        android:drawable="@drawable/drawableD"/>
 
    <!-- specify a transition -->
    <transition android:fromId="@+id/default" android:toId="@+id/pressed">
        <animation-list>
            <item android:duration="15" android:drawable="@drawable/dt1"/>
            <item android:duration="15" android:drawable="@drawable/dt2"/>
            ...
        </animation-list>
    </transition>
    ...
</animated-selector>


 

   6.为矢量图片添加动画

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

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

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

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

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

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

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

<!-- res/drawable/vectordrawable.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600">
    <group
        android:name="rotationGroup"
        android:pivotX="300.0"
        android:pivotY="300.0"
        android:rotation="45.0" >
        <path
            android:name="v"
            android:fillColor="#000000"
            android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
    </group>
</vector>

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

<!-- res/drawable/animvectordrawable.xml -->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:drawable="@drawable/vectordrawable" >
    <target
        android:name="rotationGroup"
        android:animation="@anim/rotation" />
    <target
        android:name="v"
        android:animation="@anim/path_morph" />
</animated-vector>


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

<!-- res/anim/rotation.xml -->
<objectAnimator
    android:duration="6000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />


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


<!-- res/anim/path_morph.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="3000"
        android:propertyName="pathData"
        android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"
        android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"
        android:valueType="pathType" />
</set>



引用的文章:

   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/



  



本文出自 “Android - 静心之作” 博客,请务必保留此出处http://6246534.blog.51cto.com/6236534/1860012

以上是关于Android动画知识汇总的主要内容,如果未能解决你的问题,请参考以下文章

Android:将“ViewPager”动画从片段更改为片段

Android 动画嵌套片段

Android使用片段在viewpager中的页面滚动上放置动画

android小知识点代码片段

动画基础知识汇总

Android 动画布局和视图