您的位置:首页 > 移动开发 > Android开发

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

2015-01-19 08:31 357 查看
实现思路来自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!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: