美文网首页
Android动画基础

Android动画基础

作者: 家硕先生 | 来源:发表于2018-09-17 17:08 被阅读6次

1. Android中的三种动画

View动画:通过对场景里的对象不断做图像变换(平移、缩放、旋转、透明度)从而产生动画效果,它是一种渐进式动画,并且View动画支持自定义。
帧动画:通过顺序播放一系列图像从而产生动画效果,可以简单理解为图片切换动画,很显然,如果图片过多多大就会导致OOM。
属性动画:属性动画通过动态的改变对象的属性从而达到动画效果。

2. View动画

View动画对应着四个动画相关的类,它们都继承自Animation:

  • 平移动画:TranslateAnimation
  • 缩放动画:ScaleAnimation
  • 旋转动画:RotateAnimation
  • 透明度动画:AlphaAnimation

View动画的四种变换(XML与代码对照表)

名称 标签 子类 效果
平移动画 <translate> TranslateAnimation 移动View
缩放动画 <scale> ScaleAnimation 放大或缩小View
旋转动画 <rotate> RotateAnimation 旋转View
透明度动画 <alpha> AlphaAnimation 改变View的透明度

下面通过实例来展示四种动画的使用:

2.1 Translate(平移动画)

2.1.1 XML方式实现
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"        动画持续时间2秒
    android:repeatMode="reverse">  有两种重复类型,reverse倒序回放,restart从头播放
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="100"
        android:toYDelta="0"
        android:repeatCount="infinite"/><!-- 无限次重复执行动画 -->
</set>

// 通过AnimationUtils加载动画资源文件
Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate_animation);
imageView.startAnimation(animation);
2.1.2 Java代码方式实现
        Animation animation = new TranslateAnimation(0, 100, 0, 0);
        animation.setDuration(2000); // 设置动画持续时间
        animation.setRepeatCount(Animation.INFINITE); // 设置重复次数,无限次
        // 有两种重复类型,reverse倒序回放,restart从头播放
        animation.setRepeatMode(Animation.REVERSE);
        imageView.startAnimation(animation);
2.1.3 效果图:
平移动画-效果图.gif

2.2 Scale (缩放动画)

2.2.1 XML方式实现
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:repeatMode="reverse">
    <scale
        android:fromXScale="0.5"   水平方向缩放起始值
        android:fromYScale="0.5"   竖直方向缩放起始值
        android:toXScale="1"       水平方向缩放结束值
        android:toYScale="1"       竖直方向缩放结束值
        android:pivotX="50%"       缩放的轴点x坐标
        android:pivotY="50%"       缩放的轴点y坐标
        android:repeatCount="2"/>
</set>
2.2.2 Java代码方式实现
        Animation animation = new ScaleAnimation(0.5f, 1.f, 0.5f, 1.f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        animation.setDuration(1000);
        animation.setRepeatMode(Animation.REVERSE);
        animation.setRepeatCount(2);
2.2.3 效果图:
缩放动画-效果图.gif

2.3 Rotate (旋转动画)

2.3.1 XML方式实现
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000">
    <rotate
        android:fromDegrees="0"  旋转开始角度
        android:toDegrees="360"  旋转结束角度
        android:pivotX="50%"     旋转的轴点x坐标
        android:pivotY="50%"/>   旋转的轴点y坐标
</set>
2.3.2 Java代码方式实现
        Animation animation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        animation.setDuration(1000);
2.3.3 效果图:
旋转动画-效果图.gif

2.4 Alpha (透明度动画)

2.4.1 XML方式实现
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000">
<alpha android:fromAlpha="1"  透明度起始值
    android:toAlpha="0.1"/>   透明度结束值
</set>
2.4.2 Java方式实现
        Animation animation = new AlphaAnimation(1.f, 0.1f);
        animation.setDuration(1000);
2.4.3 效果图:
透明度动画-效果图.gif

3. 帧动画

帧动画是顺序播放一组预先定义好的图片,类似电影播放。系统提供了AnimationDrawable来使用帧动画,使用帧动画是通过定义一个XML文件来定义AnimationDrawable的。

<?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/dazhao_1" android:duration="100"/>
    <item android:drawable="@drawable/dazhao_2" android:duration="100"/>
    <item android:drawable="@drawable/dazhao_3" android:duration="100"/>
    ......

</animation-list>

代码使用:

        imageView.setImageResource(R.drawable.frame_animation);
        AnimationDrawable drawable = (AnimationDrawable) imageView.getDrawable();
        drawable.start();

效果图:


帧动画-效果图.gif

4. 属性动画

属性动画是API11新加入的特性,与View动画不同的是,它可以对任何对象做动画,它是通过改变对象的属性值来实现的动画效果,不局限使用在View上。

属性动画常用到的类有:

  • ValueAnimator
  • ObjectAcimator
  • AnimatorSet

4.1 ValueAnimator

        // 偏移量0~100
        ValueAnimator animator = ValueAnimator.ofFloat(0f, 100f);
        animator.setDuration(1000);
        // 当值改变的时候回调该接口,可以在里面执行view的更新操作
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // 改变view的translationX属性
                imageView.setTranslationX((float) animation.getAnimatedValue());
            }
        });
        animator.start();

从上面的代码可以得出结论,其实属性动画的本质是:一个数值控制器
通过监听数值的改变,在不断改变对象的属性,从而达到动画效果。

效果如下:


属性动画.gif

4.2 ObjectAnimator

ObjectAnimator继承自ValueAnimator,其动画机制也是依靠ValueAnimator来完成的,但是它使用起来更加方便简洁。实现上面的效果只需要:

        ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "translationX", 0f, 100f);
        animator.setDuration(1000);
        animator.start();

4.3 AnimatorSet

AnimatorSet是动画集合,用来组合多个动画效果。
还是先举个栗子:

        AnimatorSet set = new AnimatorSet();
        set.playTogether(
                ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f),
                ObjectAnimator.ofFloat(imageView, "rotationX", 0f, 360f)
        );
        set.setDuration(2000).start();

上面代码,组合了平移、旋转动画,效果如下:


组动画合.gif

4.4 插值器和估值器

4.4.1 插值器和估值器的使用
        // 给平移属性动画设置一个估值器 FloatEvaluator
        ValueAnimator animator = ObjectAnimator.ofObject(imageView, "translationX", new FloatEvaluator(),   0f, 200f);
        animator.setDuration(2000);
        // 设置插值器,该插值器的效果是“减速插值器”,即动画越来越慢
        animator.setInterpolator(new DecelerateInterpolator());
        animator.start();

上述例子只是使用了默认的插值器和估值器,imageView会向右平移,并且移动速度越来越慢(好像不是很明显>_<),效果如下:


减速平移.gif
4.4.2 理解插值器和估值器

TimeInterpolator(时间插值器)

  • 根据时间流逝的百分比计算出当前属性值改变的百分比。
  • 系统已有插值器:
    a. LinearInterpolator(线性插值器):匀速动画。
    b. AccelerateDecelerateInterpolator(加速减速插值器):动画两头慢,中间快。
    c. DecelerateInterpolator(减速插值器):动画越来越慢。

TypeEvaluator(类型估值算法,即估值器)

  • 根据当前属性改变的百分比来计算改变后的属性值。
  • 系统已有的估值器:
    a. IntEvaluator:针对整型属性
    b. FloatEvaluator:针对浮点型属性
    c. ArgbEvaluator:针对Color属性
插值器和估值器的关系

猜测:估值器是根据插值器返回的百分比来计算数值的。

下面看ValueAnimator中的一段代码:

    void animateValue(float fraction) {
       // 使用插值器计算当前百分比
        fraction = mInterpolator.getInterpolation(fraction);
        mCurrentFraction = fraction;
        int numValues = mValues.length;
        for (int i = 0; i < numValues; ++i) {
            // 没深究进去看,应该就是计算属性值
            mValues[i].calculateValue(fraction);
        }
        if (mUpdateListeners != null) {
            int numListeners = mUpdateListeners.size();
            for (int i = 0; i < numListeners; ++i) {
                mUpdateListeners.get(i).onAnimationUpdate(this);
            }
        }
    }

从源码角度可以验证上面的猜测。

关于动画基础简单介绍完毕~

相关文章

网友评论

      本文标题:Android动画基础

      本文链接:https://www.haomeiwen.com/subject/orxegftx.html