android属性动画使用方法

在android 3.0的时候,谷歌提供的Property Animation这个概念,与之前的tween动画相比,还是有明显的区别。举个最简单的例子,我们在一个imageview上面增加一个onclick事件,随后我们来一个位移动画,这时候我们再点击这个imageview,就会发现点击事件没了,然后我们又会很离奇的发现在一开始加载Imageview的那个地方,却可以响应这个点击事件,这不是很操蛋吗。。。从原理上来说,tween动画,仅仅是改变了view的绘图位置以及相关属性,没有牵扯到view本身这个对象的操作,所以才会带来如此大的麻烦。基于这一点,属性动画这个概念就很有必要去掌握。

把相关类拿出来说说 ObjectAnimator ValueAnimator PropertyValuesHolder AnimatorSet TypeEvaluator AnimatorInflater,其实对于效果展示上,两者肯定没有什么区别的,无非就是设置动画效果,动画时间,动画差值器,动画监听这几类,如果需要详细了解,请参考http://developer.android.com/guide/topics/resources/animation-resource.html#Property

下面我们来看看具体使用方法

(1)1句话演示基本用法

ObjectAnimator.ofFloat(click, "alpha", 1F, 0F).setDuration(1000).start();
简单吧,就一句话定义了alpha的操作
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)
看api,click就是执行动画的对象,propertyName就是动画属性,这里还可以选择诸如scaleX之类的多种对象,values就是动画参数值,比如我们这边如果写1F, 0F, 1F, 0F,他就会在1000毫秒内执行2次渐变效果。有个地方要注意下,就是propertyName,这个不是随便乱写的,具体有哪些我暂时也没找到完整的说明,待我后续补充

(2)联合多动画实现

跟tween一样,这边提供了animatorSet这个对象

 ObjectAnimator ani1=ObjectAnimator.ofFloat(click, "alpha", 1F, 0F);
 ObjectAnimator ani2=ObjectAnimator.ofFloat(click, "translationX", 100, 300);
 ObjectAnimator ani3=ObjectAnimator.ofFloat(click, "translationY", 100, 300);
这边写了3个动画效果

然后来一个animatorSet

AnimatorSet set=new AnimatorSet();
我们可以这样玩:一起执行

set.playTogether(ani1, ani2, ani3);
还可以这样玩:顺序执行

set.playSequentially(ani1, ani2, ani3);
还能自己安排先后顺序玩

set.play(ani1).after(ani2);
set.play(ani3).before(ani2);
是不是很牛逼
最后播放一下

set.setDuration(2000);
set.start();
注意一点就是这边是animatorSet不是animationSet


(3)写了那么多效果,我们不能忘记监听一下动画的开始与结束,也非常简单,走你

ani1.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                
            }

            @Override
            public void onAnimationEnd(Animator animation) {

            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

同样提供了动画开始、结束、取消、重复这些动作的监听。

我们这样看有时候也会觉得麻烦,比如我们只要监听动画结束,写那么多不是太乱了,OK,这边提供了AnimatorListenerAdapter,让你轻松控制自己想控制的

ani1.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }
        });
这样就可以了

(4)使用不存在的动画效果名称,去自定义视图动画

刚才我们说到了,那个propertyName如果随便乱写,是会有问题的,那我现在就是打算乱写,可不可以玩?答案是肯定的。我们来段代码

ObjectAnimator ani1=ObjectAnimator.ofFloat(click, "yd", 100, 200).setDuration(1000);
        ani1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float tranX= (float) animation.getAnimatedValue("yd");
                click.setTranslationX(tranX);
            }
        });
        ani1.start();
这边有一个自定义的动画效果“移动”,我们利用他在1000毫秒内执行100-200的这个操作,通过getAnimatedValue("yd")来获取到这个动画效果偏移值,然后再设置setTranslationX来自定义X轴的移动动画

(5)使用propertyValuesHolder去执行联合动画

之前说到用animatorSet去执行多动画效果,这边还提供了PropertyValuesHolder把多种动画同时加到一个对象上进行多动画操作,还是看代码

PropertyValuesHolder holder1=PropertyValuesHolder.ofFloat("alpha", 1F, 0F);
PropertyValuesHolder holder2=PropertyValuesHolder.ofFloat("translationX", 100, 200);
PropertyValuesHolder holder3=PropertyValuesHolder.ofFloat("translationY", 100, 200);
ObjectAnimator.ofPropertyValuesHolder(click, holder1, holder2, holder3).setDuration(1000).start();

(6)使用ValueAnimator去执行动画操作

除了ObjectAnimator,ValueAnimator同样也可以执行各种操作,只不过他也要自己来实现真实的动画过程,这点跟之前自定义动画属性差不多,看代码

ValueAnimator animator=ValueAnimator.ofFloat(0, 100);
animator.setTarget(click);
animator.setDuration(1000);
animator.start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void onAnimationUpdate(ValueAnimator animation) {
<span style="white-space:pre">		</span>click.setTranslationY((float) animation.getAnimatedValue());
        }
});
是不是跟那个几乎一模一样的写法,区别在于ValueAnimator实例化对象的时候不是把对象视图直接添加进来进行构造而已

(7)TypeEvaluator的使用

直接通过ValueAnimator构造方法去创建实例,无法使用ofFloat或者ofInt,可以通过TypeEvaluator传入不同的泛型对象来返回相应需要的值,以便于我们在onAnimationUpdate中更加方便的使用。看代码找区别

        ValueAnimator animator=new ValueAnimator();
        animator.setDuration(2000);
        animator.setObjectValues(new PointF(0, 0));
        animator.setInterpolator(new LinearInterpolator());
        animator.setEvaluator(new TypeEvaluator<PointF>() {

            @Override
            public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
                PointF pointF=new PointF();
                //随便写的自定义位置
                pointF.x=100*fraction*3;
                pointF.y=0.5f*100*fraction*3*fraction*3;
                return pointF;
            }
        });
        animator.start();
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                PointF pointF= (PointF) animation.getAnimatedValue();
                click.setTranslationX(pointF.x);
                click.setTranslationY(pointF.y);
            }
        });
这边我们选择返回了RectF这种类型对象,便于我们存储根据估值器fragction而获得的值。fraction是一个从0到1的时间因子,某种意义上也是这个动画的执行进度,也同样可以反映差值器的走势。evaluate里面返回的值,就是后面onAnimationUpdate里面的入参。

(8)使用xml文件来创建属性动画

同tween一样,可以再xml中定义好animator动画。这边有一个地方不同,就是之前我们建立的都是/anim,这边却是建立/animator

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:propertyName="scaleX"
    android:valueFrom="1.0"
    android:valueTo="2.0"
    android:valueType="floatType">

</objectAnimator>
翻译一下,就是
ObjectAnimator.ofFloat(click, "<span style="font-family: Arial, Helvetica, sans-serif;">scaleX</span><span style="font-family: Arial, Helvetica, sans-serif;">", 1F, 2F).setDuration(1000).start();</span>
在java中,我们使用AnimatorInflater去加载

Animator animator=AnimatorInflater.loadAnimator(MainActivity.this, R.animator.scalex);
animator.setTarget(click);
animator.start();

(9)使用xml文件来创建属性动画
这次我们使用set来创建xml动画

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together" >

    <objectAnimator
        android:duration="1000"
        android:propertyName="scaleX"
        android:valueFrom="1"
        android:valueTo="0.5" >
    </objectAnimator>
    <objectAnimator
        android:duration="1000"
        android:propertyName="scaleY"
        android:valueFrom="1"
        android:valueTo="0.5" >
    </objectAnimator>

</set>

注意看这边有个ordering,这个就是来描述动画们是顺序执行还是同时执行的描述

如果想在android3.0一下使用属性动画,那么请使用NineOldAndroids


基本上就这么多,要有什么意见,请各位看官指点一二




©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页