Android动画

Animation


  • Animation类是所有动画(scale、alpha、translate、rotate)的基类,以下是关于 Animation 的属性及意义:
  • android:duration 动画持续时间,以毫秒为单位
  • android:fillAfter 如果设置为true,控件动画结束时,将保持动画最后时的状态
  • android:fillBefore 如果设置为true,控件动画结束时,还原到开始动画前的状态
  • android:fillEnabled 与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态
  • android:repeatCount 重复次数
  • android:repeatMode 重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。
  • android:interpolator 设定插值器,其实就是指定的动作效果,比如弹跳效果等
scale
  • scale标签是缩放动画,可以实现动态调控件尺寸的效果,有下面几个属性:
  • android:fromXScale 起始的X方向上相对自身的缩放比例,浮点值,比如1.0代表自身无变化,0.5代表起始时缩小一倍,2.0代表放大一倍;
  • android:toXScale 结尾的X方向上相对自身的缩放比例,浮点值;
  • android:fromYScale 起始的Y方向上相对自身的缩放比例,浮点值,
  • android:toYScale 结尾的Y方向上相对自身的缩放比例,浮点值;
  • android:pivotX 缩放起点X轴坐标,可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p,当为数值时,表示在当前View的左上角,即原点处加上50px,做为起始缩放点;如果是50%,表示在当前控件的左上角加上自己宽度的50%做为起始点;如果是50%p,那么就是表示在当前的左上角加上父控件宽度的50%做为起始点x轴坐标。
  • android:pivotY 缩放起点Y轴坐标,取值及意义跟android:pivotX一样。
alpha
  • alpha是透明动画,调节控件的透明度,属性如下:
  • android:fromAlpha 动画开始的透明度,从0.0 --1.0 ,0.0表示全透明,1.0表示完全不透明
  • android:toAlpha 动画结束时的透明度,也是从0.0 --1.0 ,0.0表示全透明,1.0表示完全不透明
rotate
  • rotate是旋转动画,控制控件在平面上的旋转角度
  • android:fromDegrees 开始旋转的角度位置,正值代表顺时针方向度数,负值代码逆时针方向度数
  • android:toDegrees 结束时旋转到的角度位置,正值代表顺时针方向度数,负值代码逆时针方向度数
  • android:pivotX 旋转中点X坐标
  • android:pivotY 旋转中点Y坐标
translate
  • translate是平移动画,控制控件水平或垂直移动
  • android:fromXDelta 起始点X轴坐标,可以是数值、百分数、百分数p 三种样式
  • android:fromYDelta 起始点Y轴从标
  • android:toXDelta 结束点X轴坐标
  • android:toYDelta 结束点Y轴坐标
set
  • set定义动画的集合,可以将多个动画打包执行,在XML中set的定义方式如下:
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:fillAfter="true">

         <alpha   
             android:fromAlpha="0.0"  
             android:toAlpha="1.0"/>  
    
         <scale  
             android:fromXScale="0.0"  
             android:toXScale="1.4"  
             android:fromYScale="0.0"  
             android:toYScale="1.4"  
             android:pivotX="50%"  
             android:pivotY="50%"/>  
    
        <rotate  
             android:fromDegrees="0"  
             android:toDegrees="720"  
             android:pivotX="50%"  
            android:pivotY="50%"/>  
       
    </set> 
    
执行动画(XML)
  • 在项目的 res -> anim下定义动画(xxx.xml)
  • 在代码中加载动画,并让目标控件执行
    Animation anim = AnimationUtils.loadAnimation(this, R.anim.xxx);
    imag.startAnimation(anim);
Interpolator插值器
  • Interpolator赋予动画一些特性,它指定了动画变化的特征,系统提供的Interpolator如下:
    • AccelerateDecelerateInterpolator 在动画开始与介绍的地方速率改变比较慢,在中间的时候加速
  • AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
  • AnticipateInterpolator 开始的时候向后然后向前甩
  • AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
  • BounceInterpolator 动画结束的时候弹起
  • CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
  • DecelerateInterpolator 在动画开始的地方快然后慢
  • LinearInterpolator 以常量速率改变
  • OvershootInterpolator 向前甩一定值后再回到原来位置
  • xml动画中添加Interpolator
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
代码生成动画

前面介绍了通过xml定义动画,动画集合,插值器等,其实通过代码也可以做到.

  • ScaleAnimation
    ScaleAnimation scaleAnim = new ScaleAnimation(0.0f,1.4f,0.0f,1.4f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    scaleAnim.setDuration(700);

    //它相当于在xml如下定义
     <?xml version="1.0" encoding="utf-8"?>  
     <scale xmlns:android="http://schemas.android.com/apk/res/android"                                                                   
         android:fromXScale="0.0"  
         android:toXScale="1.4"  
         android:fromYScale="0.0"  
         android:toYScale="1.4"  
         android:pivotX="50"  
         android:pivotY="50"  
         android:duration="700" />    
    
  • AlphaAnimation
    AlphaAnimation alphaAnim = new AlphaAnimation(1.0f,0.1f);
    alphaAnim.setDuration(3000);
    alphaAnim.setFillBefore(true);

    //对应xml属性如下:
    //android:fromAlpha="1.0"  
    //android:toAlpha="0.1"  
    //android:duration="3000"  
    //android:fillBefore="true"    
    
  • RotateAnimation
    RotateAnimation rotateAnim = new RotateAnimation(0, -650, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    rotateAnim.setDuration(3000);
    rotateAnim.setFillAfter(true);

    //对应xml属性如下:
    //android:fromDegrees="0"  
    //android:toDegrees="-650"  
    //android:pivotX="50%"  
    //android:pivotY="50%"  
    //android:duration="3000"  
    //android:fillAfter="true"
    
  • TranslateAnimation
    TranslateAnimation translateAnim = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.ABSOLUTE, -80,
    Animation.ABSOLUTE, 0, Animation.ABSOLUTE, -80);
    translateAnim.setDuration(2000);
    translateAnim.setFillBefore(true);

    //对应xml属性:
    //android:fromXDelta="0"   
    //android:toXDelta="-80"  
    //android:fromYDelta="0"  
    //android:toYDelta="-80"  
    //android:duration="2000"  
    //android:fillBefore="true"
    
  • AnimationSet
    AlphaAnimation alphaAnim = new AlphaAnimation(1.0f,0.1f);
    ScaleAnimation scaleAnim = new ScaleAnimation(0.0f,1.4f,0.0f,1.4f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    RotateAnimation rotateAnim = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

    AnimationSet setAnim=new AnimationSet(true);  
    setAnim.addAnimation(alphaAnim);  
    setAnim.addAnimation(scaleAnim);  
    setAnim.addAnimation(rotateAnim);   
    setAnim.setDuration(3000);  
    
  • Interpolater
    ScaleAnimation interpolateScaleAnim=new ScaleAnimation(0.0f,1.4f,0.0f,1.4f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    interpolateScaleAnim.setInterpolator(new BounceInterpolator());
    interpolateScaleAnim.setDuration(3000);

Property Animator(属性动画)


ValueAnimator
  • ValueAnimator只负责对指定的数字区间进行动画运算

  • 我们需要对运算过程进行监听,然后自己对控件做动画操作

  • ValueAnimator的构件方法
    public static ValueAnimator ofInt(int... values)
    public static ValueAnimator ofFloat(float... values)

     //他们的参数类型都是可变参数长参数,所以我们可以传入任何数量的值;传进去的值列表,就表示动画时的变化范围;
     //比如ofInt(2,90,45)就表示从数值2变化到数字90再变化到数字45;所以我们传进去的数字越多,动画变化就越复杂。
     //从参数类型也可以看出ofInt与ofFloat的唯一区别就是传入的数字类型不一样,
     //ofInt需要传入Int类型的参数,而ofFloat则表示需要传入Float类型的参数。 
    
  • ValueAnimator的常用函数
    //设置动画时长,单位是毫秒
    ValueAnimator setDuration(long duration)
    //获取ValueAnimator在运动时,当前运动点的值
    Object getAnimatedValue();
    //开始动画
    void start()
    //设置循环次数,设置为INFINITE表示无限循环
    void setRepeatCount(int value)
    //设置循环模式 value取值有RESTART,REVERSE,
    void setRepeatMode(int value)
    //取消动画
    void cancel()
    //设置插值器
    void setInterpolator(TimeInterpolator value)
    //延时多久时间开始,单位是毫秒
    void setStartDelay(long startDelay)
    //完全克隆一个ValueAnimator实例,包括它所有的设置以及所有对监听器代码的处理
    ValueAnimator clone()

  • 举例说明ValueAnimator的使用方式
    ValueAnimator animator = ValueAnimator.ofFloat(0f,400f,50f,300f);
    animator.setDuration(3000);
    //监听动画变化时的实时值
    animator.addUpdateListener(
    new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
    //获取当前的值(这里传入的是float,所以强转为Float)
    Float curValueFloat = (Float)animation.getAnimatedValue();
    int curValue = curValueFloat.intValue();
    //跟随值的变化,而改变控件的属性
    tv.layout(curValue,curValue,curValue+tv.getWidth(),
    curValue+tv.getHeight());
    }
    });
    animator.start();

  • ValueAnimator 监听
    /**
    * 监听器一:监听动画变化时的实时值
    */
    public static interface AnimatorUpdateListener {
    void onAnimationUpdate(ValueAnimator animation);
    }
    //添加方法为:
    //public void addUpdateListener(AnimatorUpdateListener listener)
    //移除的方法
    //void removeUpdateListener(AnimatorUpdateListener listener);
    //void removeAllUpdateListeners();

    /** 
     * 监听器二:监听动画变化时四个状态 
     */  
     public static interface AnimatorListener {  
       void onAnimationStart(Animator animation);  
       void onAnimationEnd(Animator animation);  
       void onAnimationCancel(Animator animation);  
       void onAnimationRepeat(Animator animation);  
    }  
    //添加方法为:
    //public void addListener(AnimatorListener listener)  
    //void removeListener(AnimatorListener listener);  
    //void removeAllListeners(); 
    
  • 自定义Interpolator
    public class MyInterpolator implements Interpolator {

       public LinearInterpolator() {  
       }  
    
       public LinearInterpolator(Context context, AttributeSet attrs) {  
       }  
    
       public float getInterpolation(float input) { 
          // input表示动画的时间进度,范围是0到1,随着动画的执行匀速增长
          // 返回值表示动画的实际进度,是关于input的一维函数
          // 当前的值 = start + (end- start)* 动画进度
          return input;  
       }  
    }  
    
  • Evaluator

    • 插值器的进度,是如何转换为动画实际的值?
      Evaluator就是将动画进度转换为实际值的东西,它定义了转换的规则.
    • FloatEvaluator 和 IntEvaluator分别对应 ofFloat() 和 ofInt()
      当我们定义动画的时候,如果不显示的添加Evaluator,则使用默认的Evaluator
      public class IntEvaluator implements TypeEvaluator<Integer> {
      public Integer evaluate(float fraction,
      Integer startValue, Integer endValue) {
      int startInt = startValue;
      //当前的值 = start + (end- start)* 动画进度
      //可以自定义规则
      return (int)(startInt + fraction * (endValue - startInt));
      }
      }
  • ArgbEvaluator (用于处理颜色值过渡转换)
    public class ArgbEvaluator implements TypeEvaluator {
    public Object evaluate(float fraction,
    Object startValue, Object endValue) {
    int startInt = (Integer) startValue;
    int startA = (startInt >> 24);
    int startR = (startInt >> 16) & 0xff;
    int startG = (startInt >> 8) & 0xff;
    int startB = startInt & 0xff;

            int endInt = (Integer) endValue;  
            int endA = (endInt >> 24);  
            int endR = (endInt >> 16) & 0xff;  
            int endG = (endInt >> 8) & 0xff;  
            int endB = endInt & 0xff;  
    
            return (int)((startA + (int)(fraction * (endA - startA))) << 24) |  
               (int)((startR + (int)(fraction * (endR - startR))) << 16) |  
               (int)((startG + (int)(fraction * (endG - startG))) << 8) |  
               (int)((startB + (int)(fraction * (endB - startB))));  
          }  
     }  
    
     ...
     //使用例子
      ValueAnimator animator = ValueAnimator.ofInt(0xffffff00,0xff0000ff);                                                                    
      animator.setEvaluator(new ArgbEvaluator());  
      animator.setDuration(3000);  
    
      animator.addUpdateListener(
              new ValueAnimator.AnimatorUpdateListener() {  
         @Override  
         public void onAnimationUpdate(ValueAnimator animation) {  
             int curValue = (int)animation.getAnimatedValue();  
             tv.setBackgroundColor(curValue);  
         }  
      });  
      animator.start();  
    
  • ofObject()
    public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values);
    //ofObject相对于ofInt和ofFloat自由度更大些,相应也更复杂点.个人认为ofObject使用的机会不多,所以简单列举一个例子说明它的用法

      ValueAnimator animator = ValueAnimator.ofObject(new CharEvaluator(),new Character('A'),new Character('Z'));                                                                                    
      animator.addUpdateListener(
              new ValueAnimator.AnimatorUpdateListener() {  
        @Override  
        public void onAnimationUpdate(ValueAnimator animation) {  
               char text = (char)animation.getAnimatedValue();  
              tv.setText(String.valueOf(text));  
        }  
      });  
      animator.setDuration(10000);  
      animator.setInterpolator(new AccelerateInterpolator());  
      animator.start();  
    
      //... 自定义Evaluator
      
      public class CharEvaluator implements TypeEvaluator<Character> {  
           @Override  
           public Character evaluate(float fraction,
                        Character startValue, Character endValue) {  
                int startInt  = (int)startValue;  
                int endInt = (int)endValue;  
                int curInt = (int)(startInt + fraction *(endInt - startInt));  
                char result = (char)curInt;  
                return result;  
            }  
       }  
    
ObjectAnimator
  • ValueAnimator使用相对比较麻烦,谷歌在ValueAnimator的基础上派生了ObjectAnimator,所以ObjectAnimator可以视为ValueAnimator的封装,使用起来更简单.
    public static ObjectAnimator ofInt(Object target, String propertyName, int... values)
    public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)

     ...
     //以下是透明,旋转,位移,缩放动画的定义
     ObjectAnimator animator =  ObjectAnimator.ofFloat(tv,"alpha",1,0,1);  
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotation",0,180,0);   
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotationX",0,270,0);
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotationY",0,180,0);
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "translationX", 0, 200,-200,0);
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "translationY", 0, 200,-100,0);
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "scaleX", 0, 3, 1); 
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "scaleY", 0, 3, 1);
    
  • why ? 为什么通过一段字符串,就可以执行指定的动画?

    • 其实上面这些属性,都有其对应的set函数:
      • setAlpha()
      • setRotation() / setRotationY() / setRotationX()
      • setTranslationY() / setTranslationX()
      • setScaleX() / setScaleY()
        当我们使用以上方式定义属性动画时,系统会拼接出目标控件对应的set函数,然后通过反射执行.
        依次类推,只要控件有某一set函数,我们就可以定义对应的动画,比如:
        //setBackgrounColor()
        ObjectAnimator animator = ObjectAnimator.ofInt(tv, "BackgroundColor", 0xffff00ff, 0xffffff00, 0xffff00ff);
        animator.setDuration(8000);
        animator.setEvaluator(new ArgbEvaluator());
        animator.start();
        进一步,自定义控件的时候,我们可以自定义set函数,都可以使用对应的动画
  • 因为ObjectAnimator派生自ValueAnimator,所以ValueAnimator其它的函数,它都可以使用,这里不再叙述

  • 属性的get函数又有何作用呢 ?
    我们已经知道属性的set函数的作用,那么对应的get函数有没有什么特殊的作用呢?
    有,OberjectAnimator的构件方法,所需的值都是可变参数,如果只传入一个值呢?动画该怎么执行?
    当只有一个值的时候,这个值将是动画的结束值,而开始值,则由相应的get函数返回

  • PropertyValuesHolder
    PropertyValuesHolder也可以用来构造动画,事实上,前面我们讲的动画的构造,最终都是通过PropertyValuesHolder完成,并且PropertyValuesHolder可以让多个动画效果一起执行,先看下几个系统的函数:
    // ObjectAnimator
    public static ObjectAnimator ofPropertyValuesHolder(Object target,PropertyValuesHolder... values)
    // PropertyValuesHolder
    public static PropertyValuesHolder ofFloat(String propertyName, float... values)
    public static PropertyValuesHolder ofInt(String propertyName, int... values)
    public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator,Object... values)
    public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values)

    // 其实已经很明显了,我们可以使用PropertyValuesHolder 构建具体的动画效果, 
    //然后使用 ObjectAnimator 的 ofPropertyValuesHolder函数将一个或多个PropertyValuesHolder 打包创建为动画对象
    //以下是 使用PropertyValuesHolder 创建动画的例子:
    PropertyValuesHolder rotationHolder = PropertyValuesHolder.ofFloat("Rotation", 60f, -60f, 40f, -40f, -20f, 20f, 10f, -10f, 0f);  
    PropertyValuesHolder colorHolder = PropertyValuesHolder.ofInt("BackgroundColor", 0xffffffff, 0xffff00ff, 0xffffff00, 0xffffffff);  
    ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mTextView, rotationHolder, colorHolder);  
    animator.setDuration(3000);  
    animator.setInterpolator(new AccelerateInterpolator());  
    animator.start(); 
    
    //关于ofObject的使用方与ObjectAnimator的ofObject大同小异...
    //ofKeyframe会在下面具体讲解
    
  • Keyframe(关键帧)
    之前我们知道,通过插值器和Evaluator可以控制动画的变化速率,但如果要实现更复杂的效果,就需要定义更复杂的公式.Keyframe同样可以控制动画的速率,使用起来也更简单.在讲自定义插值器的时候,曾提到过,动画的进度在0~1之间,而Keyframe可以让我们指定动画在某一进度点上的值,通过这种方式,我们可以更灵活,更简单的控制动画的速率.
    //动画开始的值为 0
    Keyframe frame0 = Keyframe.ofFloat(0f, 0);
    //动画进度为0.1的时候,值为 -20
    Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);
    //动画结束的时候,值为 0
    Keyframe frame2 = Keyframe.ofFloat(1, 0);
    //通过 Keyframe 构建 PropertyValuesHolder
    PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation",frame0,frame1,frame2);
    Animator animator = ObjectAnimator.ofPropertyValuesHolder(mImage,frameHolder);
    animator.setDuration(1000);
    animator.start();

    //使用Keyframe,每两帧之间默认匀速执行,即线性插值器,更强大的是,我们可以给Keyframe指定插值器,
    //如果给某个Keyframe设置了插值器,那么从前一帧到这一帧的动画会按插值器执行
    public void setInterpolator(TimeInterpolator interpolator)
    
    //同样的,Keyframe的构建方式也有以下几种
    public static Keyframe ofInt(float fraction, int value)  
    public static Keyframe ofFloat(float fraction, float value)
    public static Keyframe ofObject(float fraction, Object value)
    
    //***需要强调的是,使用Keyframe的时候,最少需要两帧,否则会报错
    //***另外第一帧是动画的开始,最后一帧是动画的结束
    
  • AnimatorSet
    顾名思义,AnimatorSet可以联合多个动画一起执行:
    //多个动画顺序执行
    public void playSequentially(Animator... items);
    public void playSequentially(List<Animator> items);
    //多个动画同时执行
    public void playTogether(Animator... items);
    public void playTogether(Collection<Animator> items);

    //以上方式都比较简单, 我们可以使用AnimatorSet.Builder实现更具体的控制,比如指定动画的执行顺序
    // 执行动画
    public Builder after(Animator aim)
    //和前面动画一起执行
    public Builder with(Animator anim)
    //先执行前面的动画,再执行这个动画
    public Builder before(Animator anim)
    //先执行这个动画,再执行前面的动画
    public Builder after(Animator anim)
    
    //示例如下
    ObjectAnimator tv1BgAnimator = ObjectAnimator.ofInt(mTv1, "BackgroundColor", 0xffff00ff, 0xffffff00, 0xffff00ff);
    ObjectAnimator tv1TranslateY = ObjectAnimator.ofFloat(mTv1, "translationY", 0, 400, 0);
    ObjectAnimator tv2TranslateY = ObjectAnimator.ofFloat(mTv2, "translationY", 0, 400, 0);
    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.play(tv1TranslateY).with(tv2TranslateY).after(tv1BgAnimator);
    animatorSet.setDuration(2000);
    animatorSet.start();
    
  • AnimatorSet 可以通过*addListener(AnimatorListener listener) *监听其状态的变化

  • 需要注意的是,某些属性可以通过AnimatorSet统一设置,比如: 动画时长,重复次数等.并且如果统一设置了这些属性,那么针对单个动画的设置将无效.

  • 使用XML定义属性动画

    • 在xml中对应animator总共有三个标签,分别是

<animator /> 对应ValueAnimator
<objectAnimator /> 对应ObjectAnimator
<set /> 对应AnimatorSet

  • animator (以下是animator完整的字段,及对应的值类型)
    <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"]
    android:interpolator=["@android:interpolator/XXX"]/>

    • android:duration:每次动画播放的时长
    • android:valueFrom:初始动化值;取值范围为float,int和color,如果取值为float对应的值样式应该为89.0,取值为Int时,对应的值样式为:89;当取值为clolor时,对应的值样式为 #333333;
    • android:valueTo:动画结束值;取值范围同样是float,int和color这三种类型的值;
    • android:startOffset:动画激活延时;对应代码中的startDelay(long delay)函数;
    • android:repeatCount:动画重复次数
    • android:repeatMode:动画重复模式,取值为repeat和reverse;repeat表示正序重播,reverse表示倒序重播
    • android:valueType:表示参数值类型,取值为intType和floatType;与android:valueFrom、android:valueTo相对应。如果这里的取值为intType,那么android:valueFrom、android:valueTo的值也就要对应的是int类型的数值。如果这里的数值是floatType,那么android:valueFrom、android:valueTo的值也要对应的设置为float类型的值。非常注意的是,如果android:valueFrom、android:valueTo的值设置为color类型的值,那么不需要设置这个参数;
    • android:interpolator:设置加速器
  • objectAnimator
    objectAnimator对比animator多了一条属性
    android:propertyName="string"

    • android:propertyName:对应属性名,即ObjectAnimator所需要操作的属性名
  • set(set标签只有一条属性)
    <set android:ordering=["together" | "sequentially"]>

    • android:ordering:表示动画开始顺序。together表示同时开始动画,sequentially表示逐个开始动画
  • 加载XML里定义的动画
    ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(context,R.animator.animator);
    valueAnimator.start();

     ObjectAnimator animator = (ObjectAnimator) AnimatorInflater.loadAnimator(MyActivity.this, R.animator.object_animator);
     animator.setTarget(mTv1);
     animator.start();
    
     AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(MyActivity.this, R.animator.set_animator);
     set.setTarget(mTv1);
     set.start();
    
布局动画

LayoutAnimation
  1. XML实现
    <?xml version="1.0" encoding="utf-8"?>
    <layoutAnimation
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:delay="1"
    android:animationOrder="normal"
    android:animation="@anim/slide_in_left"/>

    ...
    
    <ListView android:id="@+id/listview" 
            android:layout_width="match_parent" 
            android:layout_height="match_parent" 
            android:layoutAnimation="@anim/layout_animation" />
    
  2. 代码实现
    //得到一个LayoutAnimationController对象;
    LayoutAnimationController controller = new LayoutAnimationController(animation);
    //设置控件显示的顺序;
    controller.setOrder(LayoutAnimationController.ORDER_REVERSE);
    //设置控件显示间隔时间;
    controller.setDelay(0.3f);
    //为ListView设置LayoutAnimationController属性;
    mListView.setLayoutAnimation(controller);
    mListView.startLayoutAnimation();

  3. 各字段解释
    delay:指每个Item的动画开始延时,取值是android:animation所指定动画时长的倍数,取值类型可以是float类型,也可以是百分数,默认是0.5;比如我们这里指定的动画是@anim/slide_in_left,而在slide_in_left.xml中指定android:duration=”1000”,即单次动画的时长是1000毫秒,而我们在这里的指定android:delay=”1”,即一个Item的动画会在上一个item动画完成后延时单次动画时长的一倍时间开始,即延时1000毫秒后开始。
    animationOrder:指viewGroup中的控件动画开始顺序,取值有normal(正序)、reverse(倒序)、random(随机)
    animation:指定每个item入场所要应用的动画。仅能指定res/aim文件夹下的animation定义的动画,不可使用animator动画。

GridLayoutAnimation
  1. XML实现
    <?xml version="1.0" encoding="utf-8"?>
    <gridLayoutAnimation
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:rowDelay="75%"
    android:columnDelay="60%"
    android:directionPriority="none"
    android:direction="bottom_to_top|right_to_left"
    android:animation="@android:anim/slide_in_left"/>

    ***
    
    <GridView android:id="@+id/grid" 
          android:layout_width="match_parent" 
          android:layout_height="match_parent" 
          android:columnWidth="60dp" 
          android:gravity="center" 
          android:horizontalSpacing="10dp"           
          android:layoutAnimation="@anim/gride_animation"  
          android:numColumns="auto_fit" 
          android:stretchMode="columnWidth" 
          android:verticalSpacing="10dp"/>
    
  2. 代码实现
    GridLayoutAnimationController controller = new GridLayoutAnimationController(animation);
    controller.setColumnDelay(0.75f);
    controller.setRowDelay(0.5f);
    controller.setDirection(GridLayoutAnimationController.DIRECTION_BOTTOM_TO_TOP|GridLayoutAnimationController.DIRECTION_LEFT_TO_RIGHT);
    controller.setDirectionPriority(GridLayoutAnimationController.PRIORITY_NONE);
    grid.setLayoutAnimation(controller);
    grid.startLayoutAnimation();

  3. 各属性解释
    rowDelay:每一行动画开始的延迟。与LayoutAnimation一样,可以取百分数,也可以取浮点数。取值意义为,当前android:animation所指动画时长的倍数。 columnDelay:每一列动画开始的延迟。取值类型及意义与rowDelay相同。 directionPriority:方向优先级。取值为row,collumn,none,意义分别为:行优先,列优先,和无优先级(同时进行);
    direction:gridview动画方向。 取值有四个:
    *left_to_right:列,从左向右开始动画
    right_to_left :列,从右向左开始动画
    top_to_bottom:行,从上向下开始动画
    bottom_to_top:行,从下向上开始动画 *
    这四个值之间可以通过“|”连接,从而可以取多个值。
    很显然left_to_right和right_to_left是互斥的,
    top_to_bottom和bottom_to_top是互斥的。
    如果不指定 direction字段,
    默认值为left_to_right | top_to_bottom;
    即从上往下,从左往右。
    animation: gridview内部元素所使用的动画。

布局增加/移除动画
  1. android:animateLayoutChanges="true"
    只要给布局添加该属性,它内部的控件在添加和删除时,是会带有默认动画
  2. LayoutTransaction ,允许我们自定义动画效果
    LayoutTransaction transitioner = new LayoutTransition();
    ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f);
    //设置动画
    //第一个参数int transitionType:表示当前应用动画的对象范围,取值有:
    //APPEARING —— 添加元素的动画
    //DISAPPEARING —— 移除元素的动画
    //CHANGE_APPEARING —— 添加元素时,其它元素的动画(该动画必须通过PropertyValuesHolder创建)
    //CHANGE_DISAPPEARING —— 移除元素时,其它元素的动画(该动画必须通过PropertyValuesHolder创建)
    //第二个参数Animator animator:表示当前所选范围的控件所使用的动画。
    transitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut);
    //将LayoutTransaction设置进ViewGroup
    linearLayout.setLayoutTransition(mTransitioner);
    因为LayoutTransaction 使用的机会不多,且实际应用相对麻烦,所以不再详细说明
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容