Android属性动画--基础使用

Android属性动画–基础使用

转载请注明出处,谢谢~~
首先这篇文章是第一次用Markdown编写的,有什么问题(格式上的)请大家谅解。
- Android动画的概述
- 属性动画的介绍
- 属性动画的基本使用


目录

Android动画概述

  • 关于Android动画的概述,我以前写了一篇Google的译文,那篇译文就是对Android动画的一个overview。—— Android 动画概述

属性动画介绍

引进于Android3.0(API level 11),它是根据控件的属性进行动画,包括那些没有渲染到屏幕上的。这个动画系统是可扩展的,而且能非常好的自定义你的动画属性。

属性动画的API包含了属性动画所有的方法,在这里就不一一列举了,这里主要说明下本文将要详细说明的API。

  • ObjectAnimator
  • ValueAnimator
  • AnimatorSet
  • AnimatorInflater
  • View.animate()
  • TypeEvaluator
  • TimeInterpolator

这是属性动画的最基本的几种使用方法 ,下面一一说明。

属性动画的基本使用

属性动画的使用其实很简单,当然,凡事有个循序渐进,我们先从最简单的说起,就像我们写博客,从基础写起,不可能一下就写到框架搭建。

ObjectAnimator的使用

最基本的使用 

/**
     * 根据属性值设置不同的属性动画
     * @param view  属性的所有者
     * @param property  属性名称
     * @param from  初始值
     * @param to    结束值
     */
    public static void startObj(View view,String property,float from , float to){
        ObjectAnimator.ofFloat(view, property, from , to)
                        .setDuration(500)
                        .start();
    }

这样就定义了一个属性动画,然后我们在activity里调用一下:

if (flag%2 == 0) {
    ObjectAnim.startObj(iv_obj,"rotationY", 0.0F, 360.0f);
}else{
    ObjectAnim.startObj(iv_obj,"rotationX", 0.0F, 360.0f);
}
flag += 1;

看下效果:
技术分享

这里的ofFloat、ofInt、ofObject等是属性对应的数据类型,不同的属性对应不同的数据类型,里面的值分别是view,view的属性,初始值,结束值。有的时候可以不设置初始值,那就会从当前的值变化到结束值。以后的方法也是这样。
下面我们用两种方法来实现一下ObjectAnimator的多动画效果:

  • 第一种

    /**
     * 通过ObjectAnimator实现多动画同时操作
     * @param view   要操作的view
     * @param from   初始值
     * @param to     结束值
     */
    public static void startObj(final View view,float from ,float to){
        //这里将属性设为ocean是以为Android不认识这个属性,所以不会做任何改变,而我们要用from和to,所以就这样设定。
        ObjectAnimator anim = ObjectAnimator.ofFloat(view, "ocean", from , to);//这里的参数可以设置三个,就是先小后大了。
        anim.setDuration(2000);
        anim.start();
        anim.addUpdateListener(new AnimatorUpdateListener() {
    
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float x = (Float) animation.getAnimatedValue();
                view.setAlpha(x);
                view.setScaleX(x);
                view.setScaleY(x);
            }
        });
    }

    用欺骗Android的方式来实现,让动画运行,但却不改变任何属性,而我们拿到运行过程中属性值的改变,这样就可以自己动手改变我们想改变的任何属性。

  • 效果图:
    技术分享

  • 第二种

/**
     * 使用PropertyValuesHolder来实现ObjectAnimator的多属性动画
     * @param view  要操作的控件
     */
    public static void startObj(View view){
        //这里可以加上对rotation的判断
        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view,
                PropertyValuesHolder.ofFloat("scaleX",1.0f, 0.0f,1.0f),//这里的参数设置三个,先小后大。
                PropertyValuesHolder.ofFloat("scaleY", 1.0f,0.0f,1.0f),
                PropertyValuesHolder.ofFloat("alpha", 1.0f,0.0f,1.0f)
        ).setDuration(2000);
        animator.setInterpolator(new LinearInterpolator());
        animator.start();
    }
  • 效果图
    技术分享

ValueAnimator的使用

首先,ValueAnimator和ObjectAnimator肯定是有区别的,那么用ValueAnimator如何实现单动画和多动画呢?我们从代码看区别:
- 单动画

/**
     * 设置view的平移动画,可设置X或Y方向的平移
     * @param view  要平移的view
     */
    public static void startValue(final View view,final String orientation,float from,float to){
        ValueAnimator anim = ValueAnimator.ofFloat(from,to);
        anim.setTarget(view);
        anim.setDuration(2000);
        anim.setInterpolator(new AccelerateInterpolator());
        anim.start();
        anim.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                if (orientation.equals("y")) {
                    view.setTranslationY((Float)animation.getAnimatedValue());
                }else{
                    view.setTranslationX((Float)animation.getAnimatedValue());
                }
            }
        });
    }

代码中就可以看出,ValueAnimator居然没有设置改变的属性,这岂不是无效么??没错,就是无效,但是,无效是指的没有设置UpdateListener的时候,设置了监听器,想改变什么就是我们说了算的 。

  • 效果图
    技术分享
    上面那个AccelerateInterpolator()没看懂么???先忽略,后边会有详细介绍的。

然后我们看看如何实现多动画:

/**
     * 抛物线
     * @param view
     * @param ratio  移动一定的高度需要移动的宽度的比值(由于比值一直无法精确,所以在调用时就放弃了这个值,采用物理公式计算)
     * @param from
     * @param to
     */
    public static void startValue(final View view,final float ratio,float from,float to){
        ValueAnimator anim = ValueAnimator.ofFloat(from,to);
        anim.setTarget(view);
        anim.setDuration(2000);
        anim.setInterpolator(new AccelerateInterpolator());
        anim.start();
        anim.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (Float) animation.getAnimatedValue();//value的值范围是0-1
                view.setTranslationX(200 * value * 3);//看不懂不用纠结,这是物理公式,回想下抛物线的x,y位移计算公式吧
                view.setTranslationY(0.5f * 200 * value*3 * value * 3);
            }
        });

    }

依然上一个效果图:
技术分享

自由落体这里就是涉及了一个屋里公式,我也不知道对不对,从别人那问的,哈哈,不对勿喷。

AnimatorSet的使用

AnimatorSet分为同时执行和顺序执行,这两种执行方式需要我们手动设定,看名字就知道这是一个动画集合,所以单动画,只要大家不傻,是不会用它的,哈哈

  • 一起执行
/**
     * 利用AnimatorSet同时执行动画
     * @param view
     */
    public static void startAnim(View view){
        ObjectAnimator obj1 = ObjectAnimator.ofFloat(view, "scaleX", 1.0f,0.5f,1.0f);
        ObjectAnimator obj2 = ObjectAnimator.ofFloat(view, "scaleY", 1.0f,0.5f,1.0f);
        ObjectAnimator obj3 = ObjectAnimator.ofFloat(view, "rotationX", 0.0f,180.0f,0.0f);
        AnimatorSet set = new AnimatorSet();
        set.setDuration(2000);
        set.setInterpolator(new LinearInterpolator());
        set.playTogether(obj1,obj2,obj3);
        set.start();
    }

看代码可知,我们设置了一个playTogether,这样便可以同时执行了。
效果图:
技术分享

  • 分步执行
    分步执行也是要设置一些分步操作,代码较同步来说略为繁琐
/**
     * 利用AnimatorSet分步骤执行动画
     * @param view
     */
    public static void startAnimSync(View view){
        ObjectAnimator obj1 = ObjectAnimator.ofFloat(view, "scaleX", 1.0f,0.5f,1.0f);
        ObjectAnimator obj2 = ObjectAnimator.ofFloat(view, "scaleY", 1.0f,0.5f,1.0f);
        ObjectAnimator obj3 = ObjectAnimator.ofFloat(view, "rotationX", 0.0f,180.0f,0.0f);
        AnimatorSet set = new AnimatorSet();
        set.setDuration(2000);
        set.setInterpolator(new LinearInterpolator());
        set.play(obj1).after(obj2);
        set.play(obj2).after(obj3);
        set.start();
    }

可以看到,这里需要设置下先后顺序,play和after.效果也是执行完一个动画才会去执行下一个。效果图:
技术分享

AnimatorSet也就这么点东西,使用起来也很方便。

AnimatorInflater的使用

AnimatorInflater是属性动画的另一种加载方式,这种加载方式类似于ViewAnimator的方式,是用xml来写动画,然后加载到代码中。首先看单一动画的情况:
这是加载的一个工具方法,所有的xml都用这个方法加载:

/**
     * 通过AnimatorInflator加载动画
     * @param context
     * @param id
     * @param view
     */
    public static void startAnim(Context context ,int id,View view){
        Animator animator = AnimatorInflater.loadAnimator(context, id);
        animator.setTarget(view);
        animator.setDuration(2000);
        animator.setInterpolator(new LinearInterpolator());
        animator.start();
    }

然后我们写xml里的动画:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" 
    android:propertyName="rotationX"
    android:duration="1000"
    android:valueType="floatType"
    android:valueFrom="0.0"
    android:valueTo="360.0">

</objectAnimator>

这里面的属性根据英文的字面意思就可以理解,然后我们调用一下:

InflatorAnim.startAnim(this, R.animator.rotation, iv_inflator);

看下效果:
技术分享

继续使用这个类,加载更多的动画,这里就涉及到了同时执行和分步执行的问题,我们先看同时执行:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:ordering="together">

    <objectAnimator 
        android:propertyName="scaleX"
        android:interpolator="@android:anim/linear_interpolator"
        android:duration="500"
        android:valueFrom="1.0"
        android:valueTo="0.5"
        android:valueType="floatType" />

    <objectAnimator 
        android:propertyName="scaleY"
        android:interpolator="@android:anim/linear_interpolator"
        android:duration="500"
        android:valueFrom="1.0"
        android:valueTo="0.5"
        android:valueType="floatType" />

    <objectAnimator 
        android:propertyName="rotationX"
        android:interpolator="@android:anim/linear_interpolator"
        android:duration="500"
        android:valueFrom="0.0"
        android:valueTo="360.0"
        android:valueType="floatType" />
</set>

可以看到,同时执行,就是在根节点上有一个android:ordering=”together”这样的属性,设置这个属性后,我们定义的所有动画都是同时执行的,看下效果:
技术分享

然后我们看下分步的xml,

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:ordering="sequentially">

    <objectAnimator 
        android:propertyName="scaleX"
        android:interpolator="@android:anim/linear_interpolator"
        android:duration="500"
        android:valueFrom="1.0"
        android:valueTo="0.5"
        android:valueType="floatType" />

    <objectAnimator 
        android:propertyName="scaleY"
        android:interpolator="@android:anim/linear_interpolator"
        android:duration="500"
        android:valueFrom="1.0"
        android:valueTo="0.5"
        android:valueType="floatType" />

    <objectAnimator 
        android:propertyName="rotationX"
        android:interpolator="@android:anim/linear_interpolator"
        android:duration="500"
        android:valueFrom="0.0"
        android:valueTo="360.0"
        android:valueType="floatType" />
</set>

可以看到,这里就是将android:ordering=”sequentially”属性修改了,我们在看下效果:

技术分享

OK,今天的讲解就到这里了,这是关于Android属性动画的一些基本使用,下一篇博客,我将会对这篇博客进行一下补充和提示一些需要注意的地方。

Demo下载地址

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。