说起属性动画或许对Android开发的你来说并不陌生,但是你了解它背后的原理吗?接下来我就把自己的一些见解罗列出来,希望能和你共勉!
首先我们就从属性动画的基本用法说起:
val view = findViewById(R.id.view)
view.animate()
.translationX(150F)
.alpha(0.5F)
.rotation(180F)
.scaleX(1.2f)
.scaleY(1.2f).apply {
duration =1000
startDelay =1000
start()
}
通过上面的代码你就能实现系统自带的一些属性动画了。和上上面代码同样的另外的动画的组合方式还有如下:
val view = findViewById(R.id.view)
val translationX = PropertyValuesHolder.ofFloat("translationX", 0F, 180F)
val alpha = PropertyValuesHolder.ofFloat("alpha", 0F, 0.5F)
val rotation = PropertyValuesHolder.ofFloat("rotation", 0F, 180F)
val scaleX = PropertyValuesHolder.ofFloat("scaleX", 0F, 1.2F)
val scaleY = PropertyValuesHolder.ofFloat("scaleY", 0F, 1.2F)
ObjectAnimator.ofPropertyValuesHolder(view, translationX, alpha, rotation, scaleX, scaleY).apply {
duration =1000
startDelay =1000
start()
}
这种方式可以和上面的效果相同,另外PropertyValuesHolder还可以持有写关键帧(Keyframe),通过修改这些不同阶段的Keyframe的值也可以实现不一样的动画,有兴趣的可以自己了解一下。
上面这种方式是单个和组合都能够执行,但是我想一个动画结束之后再执行另一个动画总不能整出好几个ViewPropertyAnimator对象依次执行吧,别着急接下来我们就开始介绍AnimatorSet。从名字你大概就能猜出这个AnimatorSet是干什么的了,不错它就是一些类动画的集合,然后我们可以单独定制各个动画的方式,其中有几个重要的方法简单介绍一下:
首先就是AnimatorSet.play()方法,点进去居然是
看到这个我们应该想到它可能内部实现了一个动画的队列,通过这个队列判断下一个需要执行的动画,在这里我们暂时不关注它的源码是怎么实现的;接着看一下AnimatorSet的其它相关方法playTogether()方法和playSequentially()方法,一个是同时执行一个是依次执行,源码如下图:
通过上述方法我们就能够向AnimatorSet中添加我们想要的动画效果和执行顺序了,最后我们调用AnimatorSet的stary()方法,动画就能播放起来了,当然了这个过程中还能加入Interpolator,AnimatorListener和AnimatorUpdateListener这个添加监听和插值器的过程在这就不做介绍了。
接下来就到了重点了我们怎么自定义自己的属性动画呢,毕竟系统提供给我们的动画并不是很丰富,但是开发过程中的动画需求通过系统自带的动画又很难实现效果,那么系统有没有提供一种方法让我们自定义属性来达到丰富的动画效果呢?就像自定义View一样,通过一些固定的流程实现我们自己的动画效果。接下来我们就来自己书写一个自定义的属性动画,代码如下图:
上述代码我们自定义了一个changAngle的属性,在onDraw()方法中我们通过改变这个属性的值达到每次绘制的内容是随着changAngle的变化而变化。有细心的读者可能会发现你这个setChangeAngle()方法怎么多了invalidate(),没错就是调用了这个invalidate()方法使得我们的当前视图无效,等待下一次UI重新渲染我们的界面,使得我们的界面得到刷新。然后我们就能通过调用下图方法就能实现动画效果:
好了到这里我们就能简单实现一个自定义的属性动画了;接下来我们来梳理一下注意点:1,首先我们需要根据需求自定义出相应的动画属性;2,给我们的属性设置相应的get()和set()注意set()方法需要调用invalidate(),3,我们就按照平常的属性动画就能操作自定义的动画了。
最后我想说的是自定义属性动画可以自定义任意类型的数据,我们例子中列举的是float类型的变量,其实属性动画支持的类型是object类型的,相信这也是为什么属性动画的类ObjectAnimator名字的由来,寓意就是支持任意类型的动画,需要了解的可以自行了解一下ObjectAnimator类中ofObject()的方法,相信会给你带来惊喜,如下图:
好了,属性动画的自定义就介绍到这里,希望能够帮助到你,内容组织不合理的地方希望大家见谅,欢迎大家留言交流,内容如有雷同纯属巧合。