昨日三大运营商再次接连发布声明,明确表示9月1日起全面取消长途费、漫游主叫费、漫游被叫费,无论何时何地通话,都不会产其他费用,只剩下语音主叫费用,且用户无需申请,自动生效。
本篇来自 CTSN 的投稿,分享了自己的一个开源自定义View,文章思路讲述的很详细,希望大家喜欢!
CTSN 的博客地址:
http://blog.csdn.net/VRoymond
效果如下:
注意看到没,有个浮动按钮,上滑到顶缩小,下滑到某个地方就展开。暂且不说上拉跟下滑的时候。主要时按钮伸缩效果如何实现呢?这个就是我们今天的主题了。
按钮拉伸思路步骤详解
如下(绘画的很粗糙,忽略):
主要是由两个圆,然后中间是一个矩形。当按钮缩小时,就是右边这个圆向左边这个圆靠近,圆心不断向左移,中间矩形宽度不断减少,可以看到矩形的宽度就是右边圆圆心的x坐标减去左边圆心x坐标。开始动手撸代码:
1. 创建一个叫 StretchableFloatingButton 的类并且继承 ViewGroup,并实现相应的方法
2. 在 onMeasure 方法终测量控件的宽高度,以及圆心半径,矩形右边的x坐标。
3. 确定左边圆圆心,右边圆圆心,以及矩形范围,并绘制出来。(注意 ViewGroup 绘制在 dispatchDraw 方法里)
左边圆心:(center,center)半径为 center
右边圆心:(width-center,center) 半径为 center
矩形范围(RectF)确定左上角和右下角坐标:(center,0,width-center,height)
4. 在布局中引用,看效果:
5. 实现缩小和展开效果
在上面我们分析到,缩小(展开),是右边圆心不断向左边靠近(远离);矩形宽度缩小(变大),也就是右边圆心x坐标不断减小(增大),达到位置时动画就结束。
改变的就是矩形范围(center,0,x,height),x 就是我们减小(增大)的值。
右边圆(x,center),x跟矩形x一致。
如何不断减小(增大)x的值?
我们可以通过 handler 不断发送消息,减少(增加)x的值并重绘,当x到达左边圆心x坐标或到达矩形右边原本x坐标位置,停止发送
定义一个方法让外部调用
看实现效果:
1. 先把小圆绘制出来。
确定圆心位置,跟左边的圆圆心一致。小圆半径为 centet-y,这里 y 指的是圆环宽度,设置初始值为20,等下我们要操作的 圆环宽度y,来控制小圆的变化。
效果如下:
2. 当整个控件放大缩小时控制圆的缩小和放大
这里要确定个比值:小圆最小时距离左边圆的宽度是固定 我们设为 y,而控件减小或增大的距离也是确定的,我们设为 x。当出现变化时,x 减少多少,y 就根据 x/y 这个比值减少多少。
y/x = 圆环最大宽度/控件拉伸总距离
在 onMesure 中确定这个比值
在控件拉伸活着放大时,的到具体的y值
效果如下:
在考虑文字拉伸的时候如果用 canvas 画文字,控制拉伸比较难控制,所以这个控件是继承 ViewGroup。默认我在里面写了个 TextView,通过 onLayout 去控制文本宽度。
1. 创建一个 TextView,并在 onMesaure 中测量宽高度。
2. 通过 onLayout 摆放 TextView 位置。确定两个坐标左上角,右下角坐标
左上角(ceter*2 +5,center-tHeight/2),+5的目的是设置间距
右下角 (tWidth + center*2+10,(center+tHeight/2)) +10设置间距
注: tX 在后面代码中来控制文本宽度。默认初始为 tX = tWidth + center*2+10。效果如下:
3. 设置 TextView 文本宽度变化比,其实就是 TextView 右下角的 x坐标 值的大小,达到拉伸目的。
TextView 最大拉伸距离就是自身,控件拉伸距离在上面我们也已经确定是矩形的宽度。当控件拉伸多少根据这个比值,TextView 对应拉伸的距离,即我我们所要求的 tX。
确定比值:TextView最大宽度/控件拉伸总距离
根据比值得到 tX,因为是改变子控件位置,需要调用 requestLayout 方法
效果如下:
最终到了我们这个控件的最后一个思路环节了。就是小图标的旋转以及变化,在原效果中,当控件拉伸时,小图标跟着旋转,并且在效果结束之后变换图片。
这里涉及到了 canvas 的 drawBitamp 方法,以及 canvas 的 roatate 旋转方法。
1. 先把小图标画出来。
确定小图标宽高度,这里我设置了固定值:小圆的半径 - 5,-5设置间距。
确定小图标左上角坐标位置。(center - iconWidth / 2,center - iconWidth / 2)
效果如下:
2. 处理旋转,这里我设置默认旋转90度。因为原效果折叠时是逆时针旋转所以是-90度。
同样的我们也是要求出旋转比。根据旋转比得出旋转值。
旋转比: 总旋转角度/控件拉伸距离
3. 根据旋转比求出旋转角度
最终效果如下:
设置自定义属性
我们写了这么多,里面的角度,图标,文字,颜色等等都是固定的,应该可以在xml代码中动态去设置它。
这里需要写自定义属性,在 valuse文件夹 创建一个 attrs 的 XML文件,编写自定义属性
在 代码中获取自定义属性值 或者 在xml中使用。
设置折叠监听事件
当控件折叠或者展开成功时,设置一个监听事件,把折叠状态以及控件自身回调出去
效果展示:
设置自己的点击监听事件
本来有自己的点击事件,为什么也要设置自己的点击事件呢。原因如下:
在效果可以看到,当我们折叠时,点击空白处,还有点击事件响应,这是我们不需要的。
这个效果出现的原因是我们的控件设置宽度是 match_parent,所以一般设置点击事件还是会响应。
如何解决这个问题呢?
我们可以在onTouchEvent事件中做拦截,这里我们要区分两种状况:
折叠状态时,可点击区域是个圆,需要判断点击的时的 x坐标和y坐标是否在圆内。在圆内响应点击事件,不在圆内不做拦截处理。
伸展状态时,可点击区域时整个控件。
代码如下:
在Activity中使用
效果展示
最后展示下最终的完成效果:
项目地址:
https://github.com/CTSN/FlodAbleButton
每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。
如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。
欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号: