1、补间动画Animation
Animation
-TranslateAnimation
-AlphaAnimation
-ScaleAnimation
-RotateAnimation
缺点:补间动画只是视觉效果改变,并没有改变控件的属性,所以尽量少用
2、属性动画Animator
Animator
-ValueAnimator 属性的值变了 视觉没变
-ObjectAnimator 属性、视觉都改变了
-TimeAnimator
属性动画是真正的改变了属性的值
例如:
1、系统属性alpha 透明度 scalex横向拉伸 scaley纵向拉伸
translationx 横向移动 translationy 纵向移动
rotation,rotationx rotationy 旋转
2、自定义控件属性 这个属性必须实现set get方法
3、使用属性动画改变控件透明度
4、使用属性动画使控件旋转
5、使用属性动画进行缩放
注意:属性动画中,
with 同时执行
after 后面执行
before 前面执行
playTogether 同时执行
playSequence 顺序执行
与补间动画相同的是,同样使用AnimatorSet方法给同一控件添加多个动画
Animator(属性动画)和Animation(补间动画)的主要区别在于前者是改变所需要动画控件的属性值,而后者就是改变视觉效果,并没有改变控件的属性值。通过这个项目对补间动画和属性动画进一步的区别和加深印象,能够熟练的掌握动画的创建和实现。
通过AnimationListener可以监听Animation的运行过程,有三个方法分别是Animation开始的时候调用,完成的时候调用,重复的时候调用。
AnimationSet,动画集合。 我们最常用的是调用其 addAnimation 将一个个不一样的动画组织到一起来,然后调用view 的 startAnimation 方法触发这些动画执行。
setAnimation是告诉该控件我待会要执行什么动画,而要执行的的动画,是需要手动添加的。并且需要父view在动画快要开启的时候,调用invalidate。需要一定的条件限制。
而startAnimation告诉该控件,我要立马执行该动画,该动画就是已经设置好的动画。调用它时就会立即开始动画。
参看这篇文章: Android动画之Interpolator插补器和TypeEvaluator估值器
Property Animation提供了Animator.AnimatorListener和Animator.AnimatorUpdateListener两个监听器用于动画在播放过程中的重要动画事件。下面是两个监听器接口和方法的一些介绍和说明:
上面讲到ViewAnimation有许多xml加载,当然PropertyAnimation也可以对应xml加载,位置为 res/animator/
animator.xml
调用就用到了AnimatorInflater类了
组合动画也可以xml加载
在 Android 3.0 中给 View 增加了一些新的属性以及相应的 getter、setter 方法。Property Animation系统可以通过修改 View 对象实际的属性值来实现屏幕上的动画效果。此外,当属性值发生变化时,Views 也会自动调用 invalidate() 方法来刷新屏幕。 View 类中新增的便于实现 property 动画的属性包括:
1 . 第一个参数:设置目标对象,即 *** 纵的view
2 . 第二个参数:设置 *** 作的动画的属性值(见上面讲解的动画属性值)
3 . 第三个参数:可变数组参数 (初始值,中间值,结束值)。可以有一个到N个,如果是一个值的话默认这个值是动画过渡值的结束值。如果有N个值,动画就在这N个值之间过渡。
针对同一个对象多个属性,同时作用多种动画
可以调用其playTogether(同时执行)、playSequentially(顺序执行)、play、before、with、after 等方法设置动画的执行顺序,然后调用其start 触发动画执行。
Android 3.0后,谷歌给View增加animate方法直接驱动属性动画。
上一篇通过在父控件绘制前景的方式展示小红点,在布局文件中配置标记控件就能为任意子控件添加小红点。实现方案是”布局文件中配置带小红点控件 id,在父控件中获取它们的坐标,并在其右上角绘制圆圈“。但这个方案有一个漏洞,当子控件做动画,即子控件尺寸发生变化时,小红点不会联动。效果入下图:在父控件的 draw() , dispatchDraw() , drawChild() 中打 log,子控件做动画时都未能捕获到联动的事件。
突然想起 androidx.coordinatorlayout.widget.CoordinatorLayout 中的 Behavior ,在 onDependentViewChanged() 中可以实时获得关联控件的属性变化。它是如何做到的?沿着调用链往上查找:
当关联子控件发生变化时,会遍历关联控件并将变换通过 onDependentViewChanged() 传递出去。沿着调用链再往上:
CoordinatorLayout 在 onAttachedToWindow() 时注册了 View 树观察者,子控件属性变化时必定会触发 View树重绘,这样就可以在 onPreDraw() 中监听到它们的属性变化。
将这套机制照搬到自定义容器控件 TreasureBox :
这样当需要绘制小红点的子控件属性发生变化时,标记控件就可以在 onPreDraw() 中收到通知:
每次 View 树重绘前都可以在 onPreDraw() 中实时获取子控件的宽高及坐标,为了避免过度重绘,只有当属性变化时,才触发父控件重绘。需要记忆上次重绘的属性,通过比较就能知道属性是否发生变更:
还需要变更下小红点绘制逻辑,之前的逻辑如下:
如果沿用这套绘制逻辑,即使父控件监听到子控件重绘,小红点也不会跟着联动。那是因为 View 的 getTop() 和 getRight() 不包含位移值:
而 getX() 和 getY() 则包含了位移值:
只需要将绘制逻辑中的 v.right 和 v.top 换成 v.x 和 v.y ,小红点就能和动画联动了。为控件添加位移和缩放动画,测试一下:
GG思密达~
。位移动画的确会联动,但缩放并没有~
打了 log 才发现,View 通过 setScale() 的方式进行动画时,它的宽高和坐标并不会发生变化。。。
但必然是有一个属性的值变化了,虽然暂且不知道它是啥?
只能打开 View 源码,遍历所有 get 开头的函数,然后把它们的值打印在 onPreDraw() 中。经过多次尝试,终于找到了一个函数,它的返回值和子控件缩放动画联动:
当子控件做缩小动画时,该函数返回的 Rect 中的 left 会变大而 right 会变小。
函数的返回值在 mLeft , mRight , mTop , mBottom 的基础上叠加了 matrix 的值。做动画的属性值最终都会反映到 matrix 上,这样一分析好像能自圆其说,即该函数会实时返回 view 因动画而改变的属性值。
如此一来,只需要记忆上一次的 Rect ,就能在下次重绘前通过比较得知子控件是否做了动画:
绘制小红点逻辑也要做响应改动:
大功告成,效果如下:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)