Android动画基础笔记

动画分类

  • 帧动画
  • 补间动画 (View 动画)
  • 属性动画

帧动画

简介

  • 需要定义好动画的每一帧,然后系统的一帧一帧的播放。
  • 缺点:因为逐帧动画的帧序列内容不一样,不但给制作增加了负担而且最终输出的文件量也很大。
  • 优点: 逐帧动画具有非常大的灵活性,几乎可以表现任何想表现的内容,而它类似与电影的播放模式,很适合于表演细腻的动画。

实现

使用java代码
  • 帧动画播放器:AnimationDrawable ,常用方法如下图:

在这里插入图片描述

  • AnimationDrawable.addFrame(Drawable,int) 方法中Drawable对象是对每一帧的图片,可以根据图片名称批量获取,如下:
  for (int i = 0; i < 7; i++) {
animationDrawable.addFrame(getResources().getDrawable(getResources().getIdentifier ("ic_frame_" + i, "mipmap", getPackageName())), 200);
       }

getResources().getIdentifier() 根据名称获取资源

使用xml
  • 在 res/drawable 文件夹中定义动画 frame.xml,如下:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
 android:oneshot="false">
<item android:drawable="@drawable/ic_fingerprint_0" android:duration="100"/>
<item android:drawable="@drawable/ic_fingerprint_1" android:duration="100"/>
<item android:drawable="@drawable/ic_fingerprint_2" android:duration="100"/>
</animation-list>
  • 然后在代码中获取到定义的动画文件,如下:
AnimationDrawable frame = (AnimationDrawable) ContextCompat.getDrawable(this, R.drawable.frame);

frame.start();

补间动画 (View 动画)

简介

  • View动画定义了渐变Alpha、旋转Rotate、缩放Scale、平移Translate四种基本动画,并且通过这四种基本动画的组合使用,可以实现多种交互效果。
  • View动画使用非常简单,不仅可以通过XML文件来定义动画,同样可以通过Java代码来实现动画过程。

实现

使用 java代码
  • 旋转动画
 /**
     * 旋转动画
     */
    private void rotateAnim() {
        /**
         参数分别是:
          开始角度
          结束角度
           X轴起始点类型
           X轴起始点值
           Y轴起始点类型
           Y轴起始点值

         * 起始点类型 :RotateAnimation.RELATIVE_TO_SELF,RotateAnimation.RELATIVE_TO_PARENT,
         * RotateAnimation.ABSOLUTE,若起始点类型为ABSOLUTE,则起始点的值是指定的值如:720,
         * 其他的是0(0%)到1(100%)按百分比
         */
        RotateAnimation animation = new RotateAnimation(0f, 360f, RotateAnimation.RELATIVE_TO_SELF,
                0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        animation.setDuration(2000);
        //动画监听
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) { }

            @Override
            public void onAnimationEnd(Animation animation) { }

            @Override
            public void onAnimationRepeat(Animation animation) { }
        });
        animation.setRepeatMode(Animation.REVERSE);//Animation.REVERSE 第二次反向;Animation.RESTART:一个方向
        animation.setInterpolator(new AccelerateDecelerateInterpolator());//修改旋转过程中的速度
        animation.setRepeatCount(200);//重复的次数
        iv.setAnimation(animation);
        //如果需要立即执行则可使用 iv.startAnimation(animation)

    }
  • 平移动画
 private void translate() {
        /**
         * 参数分别是: 
          X轴起始点类型
         X轴起始点值
         X轴终点类型
         X轴终点值
         Y轴起始点类型
         Y轴起始点值
         Y轴终点类型
         Y轴终点值

         * 起始点类型 :RotateAnimation.RELATIVE_TO_SELF,RotateAnimation.RELATIVE_TO_PARENT,
         * RotateAnimation.ABSOLUTE,若起始点类型为ABSOLUTE,则起始点的值是指定的值如,
         * 其他的是0(0%)到1(100%)按百分比
         */
        TranslateAnimation translateAnimation = new TranslateAnimation(
                TranslateAnimation.RELATIVE_TO_SELF, 0f,
                TranslateAnimation.RELATIVE_TO_SELF, 1f,
                TranslateAnimation.RELATIVE_TO_SELF, 0f,
                TranslateAnimation.RELATIVE_TO_SELF, 1f);
        translateAnimation.setDuration(2000);
        translateAnimation.setRepeatMode(Animation.REVERSE);
        translateAnimation.setRepeatCount(200);
        iv.setAnimation(translateAnimation);
    }
  • 缩放动画
 private void scale() {
        /**
         * fromX:起始X坐标上的伸缩尺寸。
         * toX:结束X坐标上的伸缩尺寸。
         * fromY:起始Y坐标上的伸缩尺寸。
         * toY:结束Y坐标上的伸缩尺寸。
         * pivotXType:X轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
         * pivotXValue:X坐标的伸缩值。
         * pivotYType:Y轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
         * pivotYValue:Y坐标的伸缩值。
         *
         * 伸缩模式 :RotateAnimation.RELATIVE_TO_SELF,RotateAnimation.RELATIVE_TO_PARENT,
         * RotateAnimation.ABSOLUTE,若伸缩模式为ABSOLUTE,则起始点的值是指定的值如
         * 其他的是0(0%)到1(100%)按百分比
         */
        ScaleAnimation scaleAnimation = new ScaleAnimation(0f, 1, 0f, 1f,
                ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
                ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
        scaleAnimation.setDuration(2000);
        scaleAnimation.setRepeatMode(Animation.REVERSE);
        scaleAnimation.setRepeatCount(200);
        iv.setAnimation(scaleAnimation);
    }
  • 渐变动画
 private void alpha() {
        AlphaAnimation alphaAnimation = new AlphaAnimation(1f, 0f);
        alphaAnimation.setDuration(2000);
        alphaAnimation.setRepeatCount(200);
        alphaAnimation.setRepeatMode(AlphaAnimation.REVERSE);
        iv.setAnimation(alphaAnimation);
    }
  • 组合动画

    private void set() {
        /**
         * shareInterpolator :使用同一个插值器
         */
         animationSet = new AnimationSet(true);
        animationSet.setDuration(2000);
        animationSet.setFillAfter(true);// 为true动画结束时,View将保持动画结束时的状态
        animationSet.setFillBefore(true);// 为true动画结束时,View将还原到开始开始时的状态
        animationSet.setRepeatMode(Animation.REVERSE);
        animationSet.setFillEnabled(true);//是否设置动画结束状态
        animationSet.setInterpolator(new AccelerateDecelerateInterpolator());
        animationSet.addAnimation(alphaAnimation);
        animationSet.addAnimation(scaleAnimation);
        animationSet.addAnimation(translateAnimation);
        iv.setAnimation(animationSet);
    }
使用 xml文件实现
  • 在 res/anim文件夹下创建 view.xml,内容如下:
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fillAfter="true"
    android:repeatMode="restart"
    android:shareInterpolator="true">
    <alpha

        android:fromAlpha="1"
        android:toAlpha="0" />
    <rotate
        android:fromDegrees="0"
        android:pivotY="50%"
        android:toDegrees="360" />
    <scale
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="0.5"
        android:toYScale="0.5" />
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="100%"
        android:toYDelta="0" />
</set>

java代码animation 类中的方法这里都有相应的属性

  • 在代码中使用view.xml文件:
 Animation animation=AnimationUtils.loadAnimation(this, R.anim.view);
       iv.startAnimation(animation);

属性动画

简介

  • 属性动画作用的对象是任意java对象,弥补了帧动画和view动画无法对非View的对象进行动画操作的缺陷。而且可自定义各种动画效果。
  • 在一定时间间隔内,通过不断对值进行改变,并不断将该值赋给对象的属性,从而实现该对象在该属性上的动画效果
  • 工作逻辑:
    在这里插入图片描述

使用

ValueAnimator 类

  • ValueAnimator的主要方法有

    • ValueAnimator.ofInt()
    • ValueAnimator.ofFloat()
    • ValueAnimator.ofObject()
    • ValueAnimator.ofArgb()
    • ValueAnimator.ofPropertyValuesHolder()
  • 基本使用,以ofInt()为例

// 步骤1:设置动画属性的初始值 & 结束值
 // ofInt()作用有两个
        // 1. 创建动画实例
        // 2. 将传入的多个Int参数进行平滑过渡:此处传入0和1,表示将值从0平滑过渡到1
        // 如果传入了3个Int参数 a,b,c ,则是先从a平滑过渡到b,再从b平滑过渡到C,以此类推
        // ValueAnimator.ofInt()内置了整型估值器,直接采用默认的.不需要设置,即默认设置了如///何从初始值 过渡到 结束值
ValueAnimator anim = ValueAnimator.ofInt(0, 3);
       
    
// 步骤2:设置动画的播放各种属性
        anim.setDuration(500);
        // 设置动画运行的时长
        //设置动画的插值器
         anim.setInterpolator(new AccelerateDecelerateInterpolator());
         //设置动画的估值器
        anim.setEvaluator(new IntEvaluator());
        
        anim.setStartDelay(500);
        // 设置动画延迟播放时间

        anim.setRepeatCount(0);
        // 设置动画重复播放次数 = 重放次数+1
        // 动画播放次数 = infinite时,动画无限重复
        
        anim.setRepeatMode(ValueAnimator.RESTART);
        // 设置重复播放动画模式
        // ValueAnimator.RESTART(默认):正序重放
        // ValueAnimator.REVERSE:倒序回放
     
// 步骤3:将改变的值手动赋值给对象的属性值:通过动画的更新监听器
        // 设置 值的更新监听器
        // 即:值每次改变、变化一次,该方法就会被调用一次
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {

                int currentValue = (Integer) animation.getAnimatedValue();
                // 获得改变后的值
                
                System.out.println(currentValue);
                // 输出改变后的值

        // 步骤4:将改变后的值赋给对象的属性值,
        //如:view.setX( currentValue); 改变view的x坐标

                view.setproperty(currentValue);

       // 步骤5:刷新视图,即重新绘制,从而实现动画效果,View的某些属性改变会自动调用重绘的方法,这一步可以省略
                view.requestLayout();
            }
        });

        anim.start();
        // 启动动画
    }
  • 在xml中的使用

    1. 在res/animator 文件夹中新建value.xml,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:repeatMode="reverse"
android:repeatCount="100"
android:duration="2000"
android:valueFrom="0"
android:valueTo="500" />
  1. 在代码中使用value.xml
 ValueAnimator valueAnimator= (ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.object);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                iv.setRadius((Float) animation.getAnimatedValue());
            }
        });
        valueAnimator.start();

ObjectAnimator 类

  • 主要的方法:

    • ObjectAnimator.ofInt();
    • ObjectAnimator.ofArgb();
    • ObjectAnimator.ofMultiFloat();
    • ObjectAnimator.ofObject();
    • ObjectAnimator.ofMultiInt();
    • ObjectAnimator.ofPropertyValuesHolder()
  • 在java代码中的使用

ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "rotationX", 0, 120, 240, 360);
       objectAnimator.setDuration(2000);
       objectAnimator.setRepeatCount(100);
       objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
       objectAnimator.start();
  • 在xml中的使用

    1. 在res/animator 文件夹中新建object.xml,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:repeatMode="reverse"
    android:repeatCount="100"
    android:duration="2000"
    android:valueFrom="0"
    android:valueTo="500"
    android:propertyName="scaleX"
    android:valueType="floatType" />
  1. 在代码中使用object.xml
ObjectAnimator animator1 = (ObjectAnimator)AnimatorInflater.loadAnimator(this, R.animator.object);
        animator1.setTarget(iv);
        animator1.start();

组合动画 AnimatorSet

  • 使用java代码
//使用ObjectAnimator
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "radius", 0, 120, 240, 360);
        objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
        
        //使用ValueAnimator
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 120, 240, 360);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                iv.setRadius(value);
            }
        });
        AnimatorSet animatorSet=new AnimatorSet();
        animatorSet.setDuration(2000);
        animatorSet.playSequentially(objectAnimator,valueAnimator);//动画顺序播放
        animatorSet.playTogether(objectAnimator,valueAnimator);//动画同时播放
        /*
        *还可以使用BUilder指定播放顺序
         animatorSet.play(objectAnimator1)
                .after(valueAnimator1)
                .before(objectAnimator2)
                .with(objectAnimator2);
                */
        animatorSet.start();
  • 使用xml,在res/animator文件夹下新建set.xml,内容如下
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially">
    <animator
        android:duration="2000"
        android:propertyName="scaleX"
        android:repeatCount="100"
        android:repeatMode="reverse"
        android:valueFrom="0"
        android:valueTo="500"
        android:valueType="floatType" />
    <animator
        android:duration="2000"
        android:propertyName="scaleX"
        android:repeatCount="100"
        android:repeatMode="reverse"
        android:valueFrom="0"
        android:valueTo="500"
        android:valueType="floatType" />
</set>
  • 在代码中加载set.xml
 animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this,R.animator.set);
        animatorSet.setTarget(iv);
        animatorSet.start();

猜你喜欢

转载自blog.csdn.net/genmenu/article/details/88571304