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这个是同时执行
可能还有一些偏僻的小细节没有记,到时候用到还是直接查文档吧!!。
- Android动画--属性动画
- android动画 -- 属性动画
- Android动画-属性动画
- Android动画【属性动画】
- Android动画--属性动画
- android属性动画--布局动画
- Android 动画之属性动画
- Android中的动画,属性动画
- android-属性动画、视图动画
- Android动画之属性动画
- android动画 属性动画详解
- Android笔记----动画、属性动画
- Android动画之属性动画
- android 动画 之 属性动画
- Android动画之---属性动画
- Android动画之属性动画
- Android动画--属性动画--基础
- Android动画(三):属性动画
- 进程控制
- Hadoop 安装
- Hibernate 缓存机制
- 仿QQUI实现(1)
- Android技术简答题
- Android 属性动画
- 有参函数
- 几个GIS网站
- 站上历史浪潮的计算机(三)——诺依曼
- 【2015の复活】Hopscotch——CDQ分治
- 机房收费系统之数据查询基础篇
- linux 操作系统下登录qq的几种方式
- 超炫ViewPager实现欢迎页面动画效果-IT蓝豹
- java4Android(24)hashCode()/toString()