2023年6月28日发(作者:)
Android之Animator属性动画讲解【上】android Animator 讲解【上】⽬录1.简介2.属性动画相对补间动画和帧动画好处nimator 属性动画Animator 属性动画orSet组合动画6.使⽤XML编写动画7.动画监听器简介使⽤安卓⼿机的朋友的都知道,⼿机上⾯有⼀些效果⽐较炫酷。因为系统在⼀开始的时候就给我们提供了两种实现动画效果的⽅式:
逐帧动画(frame-by-frame animation)
补间动画(tweened animation)逐帧动画的理解⽐较简单,其实就是把⼀个完整的动画拆分成⼀张张图⽚,然后再把他们串联起来进⾏播放,有点像看视频⼀样补间动画是可以进⾏对View进⾏⼀系列的动画操作,包括淡⼊淡出、缩放、平移、旋转4种效果。在Android3.0之后官⽅给出⼀种全新的动画模式,属性动画(property animation),它的功能⾮常强⼤,弥补了之前补间动画的⼀些缺陷,⼏乎是可以完全替代掉补间动画了。属性动画相对补间动画和帧动画好处Android之前推存的补间动画是相对于View来就⾏操作的,⽐如说对view进⾏移动、缩放、旋转、淡⼊淡出等常见效果。但是如果我们的需求超出這写操作,那么补间动画就不能满⾜我们了。补间动画的扩展性能是有相当⼤的局限性的,既然补间动画不能胜任需求。那么我们就该换另⼀种更有满⾜我们扩展性能更好的动画了。属性动画为什么属性动画能胜任我们的需求呢?相对补间动画的效果,⽐如我对這个view 就⾏点击事件监听,原位置是(10,10),但是我在该为进⾏了补间动画的移动⼀个位置(100,100),当我们去点事该vew的时候,事件不会被触发,点击原来的位置(10,10)事件被触发了。为什么会這样?因为补间动画只是改变了view的显⽰效果,但是并没有改变该view位置状态,view控件依然在位置(10,10)中。Android3.0推存出来的属性动画,不仅能够实现补间动画的效果,还能填补补间动画的不⾜。属性动画是相对于属性来改变View的,所以上⾯的移动到(100,100)位置,view的 X和Y属性⾃然也是100了,所以当你点击该vewi的时候,事件在位置(100,100)触发了,在位置(10,10)没有被触发!ValueAnimator 属性动画ValueAnimator是整个属性动画机制当中最核⼼的⼀个类,前⾯我们已经提到了,属性动画的运⾏机制是通过不断地对值进⾏操作来实现的,⽽初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。它的内部使⽤⼀种时间循环的机制来计算值与值之间的动画过渡,我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运⾏的时长,那么ValueAnimator就会⾃动帮我们完成从初始值平滑地过渡到结束值这样的效果。除此之外,ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等,确实是⼀个⾮常重要的类。还有ValueAnimator的⽤法却⼀点都不复杂,我们先从最简单的功能看起吧,⽐如说想要将⼀个值从0平滑过渡到1,时长100毫秒,就可以这样写:ValueAnimator anim = t(0f, 1f);ation(100);();很简单的代码就可以构建出⼀个属性动画实例。设置的动画是100我们来看⼀下ofFloat源码public static ValueAnimator values) {ValueAnimator anim =new ValueAnimator();
atValues(values); return anim;}可以看出,這⾥的ofFloat⽅法⾥⾯可以传⼊很多个float,是以数组的形式的⼀个参数。如下代码:ValueAnimator anim = t(0f, 1f);ation(300);// 监听变化状态ateListener(new orUpdateListener() { @Override public voidonAnimationUpdate(ValueAnimator animation) {// 打印 log matedValue()
}});setAnimatorListener(anim, "没有添加控件状态下测试ofInt");();如图所⽰:从打印的值中,我们可以看出数值是从0到1变⼤的,⽽且增加不是均匀的。当然我们也可以设置均匀的增加,不过這个知识点刘下⼀章在讲解。在ValueAnimator中,我们还可以调⽤setStartDelay()⽅法来设置动画延迟播放的时间,调⽤setRepeatCount()和setRepeatMode()⽅法来设置动画循环播放的次数以及循环播放的模式,循环模式包括RESTART和REVERSE两种,分别表⽰重新播放和倒序播放的意思。需要连接的可以百度⼀下,因为这已经是很成熟的技术了。ObjectAnimator属性动画ObjectAnimator 是 ValueAnimator的⼦类,也是我们在开发中接触最多的⼀个类。既然是ValueAnimator的⼦类,那么ValueAnimator可以⽤的⽅法ObjectAnimator 当然也可以⽤了,ObjectAnimator 也是很好⽤的。⽐如想把⼀个TextView做淡⼊淡出的效果,效果是這样⼦的:不透明 》全透明》不透明》半透明》透明》不透明ObjectAnimator anim = ObjectAnimator .ofFloat(textView, "alpha", 1f, 0f, 1f, 0.5f, 0f, 1f);ation(3000);();效果如下:第⼀个参数是 给定的控件 View ,第⼆个参数可能很多⼈不理解,其实這个参数是可以随意起的,就是你可以随意传任何对象,他所负责的⼯作就是不断的向你起的這个属性对象进⾏赋值,然后根据属性值的改变在如何展⽰出来的。就拿刚刚的這个来说t(textView, "alpha", 1f, 0f, 1f, 0.5f, 0f, 1f);textView是没有存在這个 alpha 属性的,它的⽗类View也是⼀样没有這个 alpha 属性。是不是奇怪,很有属性怎么⼜变成了是属性对象?别急,慢慢跟⼤家分析,其实這个 alpha 属性不是根据View中有没有這个属性的,⽽是根据 view中是否存在 alpha 的set和get⽅法的,我们设置的动画也是⼀样哦,设置 alpha 就是为了去 view中寻找 alpha对应的 setAlpha 和 getAlpha ⽅法。不信的同学可以在 View中进⾏查询哦。第三个参数就不⽤多说了吧 ,上⾯有提到他是⼀个数组形式的参数,可以传多个对应的类型执⾏动画效果。根据上⾯的第⼆个参数是可以在View中获取set、get⽅法的,那么如果第⼆个参数是:rotation、translationX、translationY、scaleX、scaleY也是⼀样可以在View中找到他们的set和get⽅法的。说了那么多,为什么這个参数是這样⼦的,可以⾃⼰命名吗? 答案是肯定的,這个参数也可以⾃定义⾃⼰的⼀个属性名字,上⾯提到过,⽽刚刚说的那些 alpha、rotation、translationX、translationY、scaleX、scaleY 都是系统View中⾃带的set、get⽅法,也是⼀样没有這个属性名,只有对应的⽅法名。如果我们要想⾃⼰定义属性,下⼀章我们在重点学习。AnimatorSet组合动画什么是组合动画呢?组合动画就是能实现将多个动画组合到⼀起播放!实现组合动画功能主要需要借助AnimatorSet这个类,这个类提供了⼀个play()⽅法,如果我们向这个⽅法中传⼊⼀个Animator对象(ValueAnimator或ObjectAnimator)将会返回⼀个r的实例,r中包括以下四个⽅法: after(Animator anim) 将现有动画插⼊到传⼊的动画之后执⾏ after(long delay) 将现有动画延迟指定毫秒后执⾏ before(Animator anim) 将现有动画插⼊到传⼊的动画之前执⾏ with(Animator anim) 将现有动画和传⼊的动画同时执⾏看⼀下⼏个⽅法实现的效果:ObjectAnimator anim1 = ObjectAnimator .ofFloat(mTest, "translationX", 0f, 400f, -50f, 270f, -150f, 100f, 0f);ObjectAnimator anim2 = ObjectAnimator .ofFloat(mTest, "translationY", 0f, 400f, -50f, 270f, -150f, 100f, 0f);ObjectAnimator anim3 = ObjectAnimator .ofFloat(mTest, "rotation", 0f, 360f, -180f, 270f, 0f);ObjectAnimator anim4 = ObjectAnimator .ofFloat(mTest, "scaleX", 1f, 3f, 2f, 1f);AnimatorSet animSet =new AnimatorSet();ay(anim1).withwith(anim2).afterafter(anim3).before(anim4);ation(5000);();动画执⾏顺序:anim3 》anim2+anim1》anim4组合动画1ObjectAnimator anim1 = ObjectAnimator .ofFloat(mTest, "translationX", 0f, 400f, -50f, 270f, -150f, 100f, 0f);ObjectAnimator anim2 = ObjectAnimator .ofFloat(mTest, "translationY", 0f, 400f, -50f, 270f, -150f, 100f, 0f);ObjectAnimator anim3 = ObjectAnimator .ofFloat(mTest, "rotation", 0f, 360f, -180f, 270f, 0f);AnimatorSet animSet =new AnimatorSet();ay(anim1).withwith(anim2).withwith(anim3);ation(5000);();动画执⾏顺序:anim1+anim2+anim3 同时执⾏组合动画2使⽤XML编写动画除了代码编写动画,其实我们也可以在XML中编写动画。⾸先我们需要在res中新建⼀个⽂件夹 animator 来存储我们编写的动画。在XML中,我们有三种标签是可以⽤来编写动画的: < animator > 对应代码中的ValueAnimator < objectAnimator > 对应代码中的ObjectAnimator < set > 对应代码中的AnimatorSet好了,我们来实现⼀个从0到300平滑过渡的动画,在XML当中就可以这样写: android:valueFrom="0" android:valueTo="300" android:valueType="intType" />想将⼀个视图的alpha属性2秒内从1变成0,就可以这样写: android:duration="2000" android:valueFrom="1" android:valueTo="0" android:valueType="floatType" android:propertyName="alpha" />⽤ set 标签组合上⾯的动画就可以這样⼦写:< set xmlns:android="/apk/res/android" android:ordering="sequentially" > < objectAnimator android:duration="2000" android:propertyName="alpha" android:valueFrom="1" android:valueTo="0" android:valueType="floatType" / > < objectAnimator android:duration="2000" android:valueFrom="0" android:valueTo="300" android:propertyName="translationX " android:valueType="intType" / > 动画监听器动画监听器是可以随时随地的监听当前动画执⾏变化状态的。监听器的功能:监听动画开始前,动画结束,动画当前执⾏的状态都可以获取。Animator类当中就是提供了⼀个addListener()⽅法来实现這写效果的,这个⽅法接收⼀个AnimatorListener,我们只需要去实现这个AnimatorListener就可以监听动画的各种事件了。该监听器实现AnimatorListener接⼝有四个⽅法:tener(new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } }); onAnimationStart:动画开始的时候调⽤onAnimationRepeat()⽅法会在动画重复执⾏的时候调⽤onAnimationEnd()⽅法会在动画结束的时候调⽤onAnimationCancel()⽅法会在动画被取消的时候调⽤。有时候我们没有必要实现那么事件⽅法,只需要四个⽅法中的某⼀个,這时候Android提供了⼀个适配器类,叫作AnimatorListenerAdapter,使⽤这个类就可以解决掉实现接⼝繁琐的问题了,如下所⽰:tener(new AnimatorListenerAdapter() { }); 这⾥我们向addListener()⽅法中传⼊这个适配器对象,由于AnimatorListenerAdapter中已经将每个接⼝都实现好了,所以这⾥不⽤实现任何⼀个⽅法也不会报错。那么如果我想监听动画结束这个事件,就只需要单独重写这⼀个⽅法就可以了,如下所⽰:tener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { } }); 源码好了,本篇就在此完结了,下篇⽂章我们重点解析属性动画的类型和插值器
发布者:admin,转转请注明出处:http://www.yc00.com/web/1687955996a60672.html
评论列表(0条)