Android 属性动画

来源:互联网 发布:奇葩说 雷军 知乎 编辑:程序博客网 时间:2024/06/17 05:21

Android属性动画 (Property Animation)

昨天去学校的一个技术组织去面试,长这么大第一次面试紧张死了,到了那先去面试的JAVA当时太紧张,人家问我 JVM 的工作是什么我听成了Dalvik了自顾自的说了一大串(⊙﹏⊙)b……………….. ,然后去面试Android问到了一个我只听说过名字但是完全不知道名字的知识点—–属性动画,老心肝扑通扑通的啊 ~(>_<)~,回到宿舍赶紧撸了一下Android的属性动画~。

简介

大家都知道Android有两种动画一个叫补间动画 (平移,旋转,透明度,伸缩的变换)和帧动画,可能新手用的最多的就是补间动画(我就是……. ),那么属性动画是什么呢?他又有什么好处呢?

首先,补间动画并没有对View进行实质的改变只是让他看起来改变了,例如你写了一段代码利用补间动画把在屏幕左上角的Buttom移动到屏幕右下角,但是当你当你点击右下角的时候并没有触动点击事件,反而点击右上角View原来的位置会响应点击事件,所以View的实际的属性(例如X,Y坐标)没有改变他只是看起来改变了。。

你可以这样想,你在家拍了一张照然后PS了一下把背景换成了天安门,然后你发给你的朋友,你朋友一看会说“哇~你在天安门啊!”,其实你还是在家里O(∩_∩)O~。

而且属性动画不仅可以改变仅限的几种属性(平移,旋转,透明度,伸缩的变换),它还可以改变所有你可以手动set的属性。个人认为它就是一个计算器,计算出来把结果给我们然后我们把值赋给控件(也可以不是空间,你可以随意处理那些值)的属性。
下面我们就来看看如何使用属性动画。

ValueAnimator

这个类是属性动画最重要的类之一。先看看下面的代码:

demo1

    final ImageView image = (ImageView) findViewById(R.id.image);    //设置起始值是0.0 终点值是500。    ValueAnimator anim = ValueAnimator.ofFloat(0.0f, 500.0f);    //动画执行3秒    anim.setDuration(3000);    //每当动画刷新一帧的时候就会调用这个方法,我们个已通过animation拿到当前时间点计算出来的值    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {        //得到当前时间点计算得到的值            float x = (float) animation.getAnimatedValue();            设置给我们的ImageView            image.setX(x);            //改变View的横坐标重绘ImageView,有的View的方法会自动调用重绘,这里setx不调用所以我们自己调用invalidate            image.invalidate();        }    });    //动画开始    anim.start();}

看一下效果
效果图
其实我们只是用ValueAnimator计算的值手动设置给了ImageView。
下面看一个补间动画没有的。

 final ViewGroup viewGroup = (ViewGroup) findViewById(R.id.parent);    ValueAnimator anim = ValueAnimator.ofArgb(Color.BLACK, Color.RED);    anim.setRepeatCount(15);    anim.setDuration(10000);    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {            int x = (int) animation.getAnimatedValue();            viewGroup.setBackgroundColor(x);        }    });    anim.start();}

看看这个,感觉属性动画厉害了吧!!
这里写图片描述

如果我们不光有int,float值还想使用我们自定义的类怎么办?ValueAnimation没有提供别的值的处理方法啊,这就要用到ofObject方法了。其实当前时间点的值是由Evaluator 来计算的,使用ofObject需要我们来自己定义一个Evaluator,下面我们看看如何自定义Evaluator .

        ValueAnimator anim = ValueAnimator.ofObject(new TypeEvaluator<Point>() {        //自定义Evaluator来计算我们想要的结果        @Override        public Point evaluate(float fraction, Point startValue, Point endValue) {            //fraction :动画完成了百分之几,他的范围是0到1,1代表已经完成0代表未开始。            Point point = new Point();            point.x = (int) ((-1) * (startValue.x + fraction * (startValue.x - endValue.x)));            point.y = (int) ((-1) * (startValue.y + fraction * (startValue.y - endValue.y)));            return point;        }    }, new Point(0, 0), new Point(300, 300));    anim.setRepeatCount(5);    anim.setDuration(5000);    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {            Point p = (Point) animation.getAnimatedValue();            image.setX(p.x);            image.setY(p.y);            image.invalidate();        }    });    anim.start();

这里就是实现了TypeEvaluato接口,然后实现他的evaluato方法,计算出来的结果返回之后可以通过onupdateListener得到。恩,这个也挺简单的哈。


ObjectAnimation

ObjectAnimation比ValueAnimation用起来更加简单,它继承了ValueAnimation,看看下面的小demo就会了:

     //第一个参数是要改变的View,第二个是要改变的View的属性,后面两个不解释    ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(image, "alpha", 1f, 0f);    objectAnimator.setDuration(3000);    objectAnimator.setRepeatCount(10);    objectAnimator.setRepeatMode(ObjectAnimator.REVERSE);    objectAnimator.start();

效果图:
这里写图片描述

这里需要注意的是要改变的行、属性,上面用的是alpha,这个属性不许有public的set方法(例如View里面有setAlpha函数)才可以使用 (有一种特殊情况需要这个属性同时也有get方法,感觉一般不会那样写大家去官网看一下吧)。怎么样这个是不是比ValueAnimation简单多了,但是它的灵活性大大降低了。

AnimatorSet

这个和AnimotionSet一样的作用,支持几种动画同时执行。

        AnimatorSet set = new AnimatorSet();    ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(image, "alpha", 1f, 0f);    ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(image, "rotationX", 0f, 180f);    ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(image, "rotationY", 180f, 0f);              set.setDuration(10000).play(objectAnimator1).with(objectAnimator2).after(objectAnimator3);    //先播放objectAnimator3 ,之后把objectAnimator2和objectAnimator1同时播放    set.start();

AnimotionSet也说完了,这个更简单。

监听器

ValueAnimotior和ObjectAnimatior都可以通过addListener方法添加监听器

ValueAnimatorAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f);//想要监听一部分状态的话可以new AnimatorListenerAdapter()然后复习要监听的方法anim.addListener(new AnimatorListenerAdapter() {public void onAnimationEnd(Animator animation) {//处理}//监听全部状态 anim.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) {        }    });

XML实现动画

这个是最后要说的了和animotion差不多,先在res里面建立文件夹文件名字叫animator

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="3000"android:valueType="floatType"android:propertyName="alpha"android:valueFrom="1.0"android:valueTo="0.0"/>

然后在代码里:

    ObjectAnimator objectAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(context, R.animator.test);    objectAnimator.start();

多个动画一起执行(来自官方文档)

<set android:ordering="sequentially"><set>    <objectAnimator        android:propertyName="x"        android:duration="500"        android:valueTo="400"        android:valueType="intType"/>    <objectAnimator        android:propertyName="y"        android:duration="500"        android:valueTo="300"        android:valueType="intType"/></set><objectAnimator    android:propertyName="alpha"    android:duration="500"    android:valueTo="1f"/>

代码:

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,R.anim.property_animator);set.setTarget(myObject);set.start();

android:ordering=”sequentially是设置执行顺序是从上往下顺序执行,也可以设置成together这个是同时执行

可能还有一些偏僻的小细节没有记,到时候用到还是直接查文档吧!!。

0 0
原创粉丝点击