本文出自cjj的开源项目:一个炫酷的SearchView搜索动画库。
立马入主题,几乎每个App都有搜索功能,然而形式千篇一律。我举个例子吧,就微信来说:
显示一个搜索的图标,点击跳到另一个界面,输入要搜索的东西
现在大部分App都是用这种方式了。我是希望能有App把这个功能做得酷炫点,毕竟它也是用户经常要用到的,给用户良好的体验还是很重要的。 为此,我实现了别人设计的一些SearchView酷炫效果,可能不是很精致,你就勉强看看吧。
此时,如果你看完表格那些动画,喜欢上它时,想知道他们是怎么在代码中实现的,没问题,我这就手把手教你撩一个绚丽的SearchViewAnim , 呵呵,有点吹大了,说说我怎么实现的吧。
我们先对第一行表格的设计图进行仔细观察 ,效果是SearchView是由一个圆圈和一条直线(尾巴)构成的,开启动画时,尾巴慢慢消失成一点,然后这一点(dot) 进入圆圈内时,泛起波纹,在圈内四处逗留,然后在圆圈中心点停留闪烁,短暂的思考了下人生,又冲出去乖乖做一条尾巴。
咳,这是一个顿悟生命的dot啊!
相信大家通过我形象的描述已经知道效果是怎样了,现在就把刚刚描叙的画出来吧。
重写onDraw(Canvas canvas)
方法,利用画笔Paint在画布Canvas绘制一个普通的的视图,如下:
这里有两种画法:
1.横向画圆、画直线后,旋转画布45度
canvas.rotate(45, cx, cy); canvas.drawLine(cx + cr, cy, cx + cr * 2, cy, paint); canvas.drawCircle(cx, cy, cr, paint);
2.直接算出坐标点绘制
canvas.drawCircle(cx, cy, cr, paint); canvas.drawLine(cx + cr * sign, cy + cr * sign, scx, cy + cr * 2 * sign, paint);
这一步比较简单,就不多说了。
因为运行轨迹是固定的,我们把经过的路径设置给Path,在构造PathMeasure
函数(不知道PathMeasure用法的同学自己搜索学习),使用它两个方法getLength()
,.可获取dot运行路径的长度,getPosTan(float distance, float pos[],float tan[])
可根据distance可以获取dot的坐标点pos[]. 写成代码就是:
//创建0~mPathMeasure.getLength()的过度动画值 ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, mPathMeasure.getLength()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { mPro = (float) valueAnimator.getAnimatedValue(); if (null != pathMeasure) pathMeasure.getPosTan(mPro, mPos, null);//获取当前点坐标保存到mPos[] getSearchView().invalidate();//调用ondraw()函数 } });
至于dot进入圈圈时泛起的波浪效果,其实就是曲线的不断扩大而已,这里我们可以利用贝塞尔函数quadTo()
,不断改变控制点来实现该效果。
因为结束动画之后,视图和开始时一样,所以我们并不需要绘制Reset时的动画,只需重置状态就可以了,而如果是有些情况,比如动画停止后是箭头的效果,就需要要逆着回去绘制SearchView的过程了。
其他动画效果也是这样一步一步把复杂的东西简单化,最后你发现无非就是画线、画曲线、画弧、画圆这些,我就偷个懒,不讲剩下效果的的实现方式了,自己看看源码,可能比我吹水有用的多。
写这些花费的时间、精力还是挺多的,因为需要一些数学计算(我数学烂)和不断的调试才能绘制满意的效果,所以建议如果项目需要,可以在别人实现的轮子上改改就好。我们都知道,一个App只能有一种风格,所以加入很多样式的动画是没必要的,修改一种合适自己的就好。
水平有限及写的随意,该库还是有不少问题,也希望你能PR,完善它。