# 前言
最近逛 Dribbble
的时候,看到了一个非常酷的 Switcher
动画,特别喜欢,本想着试着用代码在 Android 平台来实现一下,没想到已经有实现的版本,并且作者还写了文章分享,思路清晰,各个实现关键点都讲的特别清楚,因此就译诚中文,分享大家,正如作者最后所说,大家一定要运行试试,效果非常赞!
原作者:Alexander Kolpakov 译者:依然范特稀西 地址:http://suo.im/60UJjT
# 正文开始
最近,我写了一篇关于实现 Dribbble 上的一个漂亮设计的文章。得到了很多积极的反馈,对我来说,这给了我很大的动力。我非常高兴能获得这些反馈,同时我也很乐意分享我的经验。
在本文中,我们将尝试逐步实现由 Oleg Frolov
创建的另一个精美的动画。这与上一篇文章中的复杂动画 UI 无关,它是一个自定义小控件。但是它有着非常精美漂亮的动画设计,如下所示:
swicher.gif
乍一看,实现这样的切换似乎并不简单,但我认为那是因为动画非常漂亮。如 你所见,创建相同的动画并不难。让我们一步一步地来实现它。
第一步,我们需要自定义 View, 并且实现它的 3 个构造方法:
1 | class Switcher @JvmOverloads constructor( |
# 接下来开始绘制
在默认(选中)状态下,我们的开关由 2 个圆角矩形(绿色和白色)组成
绘制它们非常简单,我们只需要计算白色矩形的位置并将偏移量 iconTranslateX
传递给 Android KTX Canvas.withTranslation
扩展即可:
1 | override fun onDraw(canvas: Canvas ?) { |
# 开始分解动画
动画部分,我们使用 ValueAnimator
来实现,使用它的 ofFloat(float... values)
方法,我们需要三个动画:
- 1、
switcherAnimator
: 切换器图标动画,从白色矩形到圆形,反之亦然 - 2、
translateAnimator
: 为切换器图标从左到右的过渡设置动画,反之亦然; - 3、
colorAnimator
: 将颜色从绿色(选中)更改为红色,反之亦然。
让我们先看一下 switcherAnimator
动画,设置 0
为动画的开始值, 1
为动画的结束值。
1 | // ... |
我们可以使用 Evgenii Neumerzhitckii 写的 BounceInterpolator
来实现反弹效果,这非常适合我们的动画场景,不了解的可以看一下这片文章:evgenii.com/blog/spring…,它解释了 BounceInterpolator
是如何工作的。
在 Android KTX addUpdateListener
扩展中,我们更新了 progress
的值,然后触发 invalidate
方法,最后重新绘制了视图。
1 | private var iconProgress = 0f |
lerp
方法类似一个线性插值器,它用于计算 iconOffset
, 反过来,它也用于计算 Swicher
图标的圆角矩形坐标。此图标的矩形从一个圆角矩形变为一个圆形(圆角半径较大的圆角矩形)。
我们使用了
postInvalidateOnAnimation()
代替postIvalidate
, 是因为我们需要平滑的动画,并且第一个方法有优势,详情请看:stackoverflow.com/questions/2…
translateAnimator
的工作方式相同,但是会更新 Swicher
图标的 x
位置。
如你所见,我们的白色圆圈就像百吉饼。我们有 2 种制作方法:
- 裁剪一个较小的圆圈
- 最简单的圆圈,只需在顶部绘制另一个小圆圈,然后用切换器颜色填充即可。
我选择较简单的一种。
这一切,没什么难的!我们现在有一个漂亮的自定义小控件并且带有精美的动画!
# 至此,我们一切都可以了
现在,我们可以使用任何类型的动画来创建自定义视图,而且我们可以稍微更改代码以创建另一个由 Oleg Frolov
设计的 Swicher
小部件。仅需将视图轮廓从圆角矩形更新为圆形,并禁用平移动画。就是这么简单。
swicherX.gif
# Talk is Chep,Just show Code
随意获取 GitHub 上的源代码,查看我的其他实现,别忘了尝试一下! Github: github.com/bitvale/Swi…