动画基本分类

Android动画可以分为帧动画、补间动画和属性动画。

动画分类
动画分类

视图动画(补间动画、帧动画)

补间动画通多对整个视图不断做图像的变换(平移、缩放、旋转、透明度)产生的动画效果,是一种渐进式动画。

逐帧动画,是通过一个接一个的加载Drawable资源来创建动画,按顺序的播放,像一个胶卷。对于视图动画,他只是单独的图片内容在变换,而不是整个视图。很显然,如果图片过多多大就会导致OOM异常。

视图动画的作用对象只能是View,在同一个图形通过在界面上进行透明度,缩放,旋转,平移的变化。

根据动画效果,补间动画分为以下4类:

  • 透明度动画(alpha)
  • 缩放动画(scale)
  • 平移动画(Translate)
  • 旋转动画(rotate)
    动画关系
    动画关系

补间动画

XML中的使用

spaceshipImage.xml

   <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@[package:]anim/interpolator_resource"
android:shareInterpolator=["true" | "false"] >
<alpha
    android:fromAlpha="float"
    android:toAlpha="float" />
<scale
    android:fromXScale="float"
    android:toXScale="float"
    android:fromYScale="float"
    android:toYScale="float"
    android:pivotX="float"
    android:pivotY="float" />
<translate
    android:fromXDelta="float"
    android:toXDelta="float"
    android:fromYDelta="float"
    android:toYDelta="float" />
<rotate
    android:fromDegrees="float"
    android:toDegrees="float"
    android:pivotX="float"
    android:pivotY="float" />
<set>
    ...
</set>
</set>
创建动画
ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
Animation myAnimation= AnimationUtils.loadAnimation(this, R.anim.filename);
spaceshipImage.startAnimation(myAnimation);
JAVA中的使用
ImageView imageView = findViewById(R.id.image_view);
    // 创建 需要设置动画的 视图View

    // 组合动画设置
    AnimationSet setAnimation = new AnimationSet(true);
    // 创建组合动画对象(设置为true)

    // 设置组合动画的属性
    setAnimation.setRepeatMode(Animation.RESTART);
    ...

    // 逐个创建子动画,不作过多描述

    // 子动画1:透明度动画
    Animation alpha = new AlphaAnimation(1,0);
    alpha.setDuration(3000);
    ...

    // 子动画2:缩放动画
    Animation scale1 = new ScaleAnimation(1,0.5f,1,0.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    scale1.setDuration(1000);
    ...

    // 子动画3:平移动画
    Animation translate = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
            TranslateAnimation.RELATIVE_TO_PARENT,0.5f,
            TranslateAnimation.RELATIVE_TO_SELF,0
            ,TranslateAnimation.RELATIVE_TO_SELF,0);
    translate.setDuration(10000);
    ...

    // 子动画4:旋转动画
    Animation rotate = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    rotate.setDuration(1000);
    rotate.setRepeatMode(Animation.RESTART);
    rotate.setRepeatCount(Animation.INFINITE);
    ...


    // 将创建的子动画添加到组合动画里
    setAnimation.addAnimation(alpha);
    setAnimation.addAnimation(rotate);
    setAnimation.addAnimation(translate);
    setAnimation.addAnimation(scale1);

    imageView.startAnimation(setAnimation);
    // 播放动画
插值器Interpolator

插值器是在XML中定义的一个动画修改器,它影响动画的变化率。这允许现有动画附加加速、减速、重复、反弹等效果。

插值器
插值器
<set android:interpolator="@android:anim/accelerate_interpolator">
...
</set>


Animation alphaAnimation = new AlphaAnimation(1,0);
alphaAnimation.setDuration(3000);
            //创建插值器对象
Interpolator interpolator = new OvershootInterpolator();
            //为动画添加插值器
alphaAnimation.setInterpolator(interpolator);
            imageView.startAnimation(alphaAnimation);

插值器 更多参考

Android动画之Interpolator(插值器)

帧动画

帧动画继承关系
帧动画继承关系
XML使用

rocket_thrust

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot=["true" | "false"] >
<item
    android:drawable="@[package:]drawable/drawable_resource_name"
    android:duration="integer" />
//如下
<item android:drawable="@drawable/wheel0" android:duration="50" />
<item android:drawable="@drawable/wheel1" android:duration="50" />
<item android:drawable="@drawable/wheel2" android:duration="50" />
<item android:drawable="@drawable/wheel3" android:duration="50" />
<item android:drawable="@drawable/wheel4" android:duration="50" />
<item android:drawable="@drawable/wheel5" android:duration="50" />
</animation-list>

   ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
rocketAnimation.start();
JAVA方式
<-- 直接从drawable文件夹获取动画资源(图片) -->
    animationDrawable = new AnimationDrawable();
    for (int i = 0; i <= 25; i++) {
        int id = getResources().getIdentifier("a" + i, "drawable", getPackageName());
        Drawable drawable = getResources().getDrawable(id);
        animationDrawable.addFrame(drawable, 100);
    }

    <-- 开始动画 -->
    btn_startFrame.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            animationDrawable.setOneShot(true);
            iv.setImageDrawable(animationDrawable);
            // 获取资源对象
            animationDrawable.stop();
             // 特别注意:在动画start()之前要先stop(),不然在第一次动画之后会停在最后一帧,这样动画就只会触发一次
            animationDrawable.start();
            // 启动动画

        }
    });

     <-- 停止动画 -->
    btn_stopFrame.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            animationDrawable.setOneShot(true);
            iv.setImageDrawable(animationDrawable);
            animationDrawable.stop();
        }
    });

属性动画

属性动画,在Android 3.0的(API级别11)引入的,该属性动画系统可以制作动画的任何对象的属性。但是一般来说,属性动画系统是首选的使用方法,因为它更灵活,并提供更多功能。

具体使用

ObjectAnimator

我们通过控制传入 ofFloat()的第二个参数preperty 或者 XML中的android:propertyName属性 来产生不同动画效果,以下为Android预置好的一些属性:即四种基本变换,透明度、平移、缩放、旋转

属性 作用 数值类型
alpha 透明度 float
translationX X方向的位移 float
translationY Y方向的位移 float
scaleX X方向的缩放倍数 float
scaleY Y方向的缩放倍数 float
rotation 以屏幕方向为轴的旋转度数 float
rotationX 以X轴为轴的旋转度数 float
rotationY 以Y轴为轴的旋转度数 float

以上大部分来自
作者:whd_Alive
链接:https://www.jianshu.com/p/a480ca619dd9

进度条动画的创建

先创建几个imageView 填充背景

paste image
paste image
paste image
paste image

然后在代码中添加属性动画

postDelayed(new Runnable() {
        @Override
        public void run() {
            ObjectAnimator objectAnimatorX = ObjectAnimator.ofFloat(imageViews[position], "scaleX", 1.2f, ratio[position]);
            objectAnimatorX.setDuration(600);
            objectAnimatorX.setInterpolator(new OvershootInterpolator());
            objectAnimatorX.setRepeatMode(ValueAnimator.REVERSE);
            objectAnimatorX.setRepeatCount(ValueAnimator.INFINITE);
            objectAnimatorX.start();

            ObjectAnimator objectAnimatorY = ObjectAnimator.ofFloat(imageViews[position], "scaleY", 1.2f, ratio[position]);
            objectAnimatorY.setRepeatCount(ValueAnimator.INFINITE);
            objectAnimatorY.setDuration(600);
            objectAnimatorY.setInterpolator(new OvershootInterpolator());

            objectAnimatorY.setRepeatMode(ValueAnimator.REVERSE);
            objectAnimatorY.start();

            ObjectAnimator alpha = ObjectAnimator.ofFloat(imageViews[position], "alpha", alphaMax, alphaMin);
            alpha.setRepeatCount(ValueAnimator.INFINITE);
            alpha.setDuration(600);
            alpha.setRepeatMode(ValueAnimator.REVERSE);
            alpha.setInterpolator(new DecelerateInterpolator());
            alpha.start();


        }
    }, (position + 1) * 90);

效果图就出来了……
but传不了动图。。

动图来了
动图来了