Android自定义控件:Android L控件点击水波纹的实现(源码 + Demo)

实现思路来自singwhatiwanna

http://blog.csdn.net/singwhatiwanna/article/details/42614953


Demo:

技术分享


一、控件的流程:

大致上如下,实际是有些偏差的大家可以自己画画

RevealLayout()--->init()--->onMeasure()--->onLayout()--->onDraw()--->dispatchTouchEvent()--->getTargetView()--->isTouchPointInView()--->-initParametersForChild()-->dispatchDraw()


二、设计思路:

1、为什么选择使用LinearLayout

从Layout去实现这个效果很大一个原因是减少代码复用,我们知道,如果只对Button,TextView等控件进行重写,很多代码其实都是相似的(几乎一样)这样我们等于不断地写一样的东西,浪费了时间,所以为了可复用的原则,我们重写一个Layout。


从dispatchDraw()里的设计我们可以知道,我们在这实现水波纹的效果,是不断的刷新控件,增大canvas绘制的圆的半径,实现视觉上圆增大的效果。


如果我们选用其他的layout,一方面可能会是绘制的内容更复杂(RelativeLayout),另一方面可能是适用性低(AbsoluteLayout)。而LinearLayout其实可以和Relative等布局结合使用,实现复杂布局,所以综合来考虑我们选用LinearLayout来实现。


2、为什么是dispatchTouchEvent()

在Android中,当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View, TouchEvent最先到达最顶层 view 的dispatchTouchEvent ,然后由  dispatchTouchEvent 方法进行分发,如果dispatchTouchEvent返回true ,则交给这个view的onTouchEvent处理,如果dispatchTouchEvent返回 false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false ,那么这个事件会从这个 view 往上传递,都是 onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“消失”,而且接收不到下一次事件。


3、为什么在dispatchTouchEvent()中使用getRawX与getRawY获得坐标

getX和getY获得的是相对于被点击的View的坐标,而getRawX获得的是相对于屏幕的坐标。而我们想要看到的水波纹效果,应该是从相对于屏幕中被点击的点向外散开水波。


4、initParametersForChild()中的mMaxRadius是什么,mTransformedCenterX又是什么

这个我觉得用一张图来解释会非常好懂

技术分享

5、dispatchDraw()是怎么绘制出水波纹的

基于前面的基础,我们在dispatchDraw()里是不断的刷新页面,在mRadius达到mMaxRadius之前,都刷新并且在canvas中绘制新的圆。延时操作是防止栈溢出和UI线程阻塞。


三、源码下载

Click Here!

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。