专栏名称: 郭霖
Android技术分享平台,每天都有优质技术文章推送。你还可以向公众号投稿,将自己总结的技术心得分享给大家。
目录
相关文章推荐
开发者全社区  ·  北大码农:每月近5w,扣税9k多 ·  昨天  
开发者全社区  ·  大佬与梁文锋第一次的接触 ·  昨天  
开发者全社区  ·  梁文锋的流量密码 ·  2 天前  
开发者全社区  ·  深圳蓝色行男跟红色女行长的瓜 ·  2 天前  
开发者全社区  ·  某上市公司90后美女投关进去了 ·  2 天前  
51好读  ›  专栏  ›  郭霖

简单实现自定义横向滚动选择View

郭霖  · 公众号  · android  · 2017-06-21 08:00

正文

今日科技快讯

昨日有人举行记者招待会,实名举报页游运营平台4399大股东蔡文胜涉嫌偷逃国家税款3.6亿元人民币。举报人称4399隐瞒重大事实,意图欺骗上市。而蔡文胜回应称2013年开始全面退出4399的管理层,已不再参与4399之后的所有经营管理活动,而举报的很多事实发生在这之后的。

作者简介

本篇是 哦罢了 的第三篇投稿,分享了自己写得横向滚动View,效果不错,希望大家喜欢。

哦罢了 的博客地址:

http://blog.csdn.net/iamdingruihaha

需求

今日产品经理让在产品里面加了个横向选择的功能,控件样子大致要求为:

网上找了好久没找到此控件,只能自己动手写了,很适合新手练习自定义View,并贡献给大家,效果如下:

其实很多滚轮控件也只是这个简单控件组合一下就可以了 。

实现思路

这里我偷懒了,没有把上、左、右三个箭头写到控件里面,写进去也简单,不过突然感觉在外面布局,写个方法出来也是蛮帅的。所以今天我们的主角就是中间的可以横向滑动的部分,乍一看就是个 recycleview,不过这里我没有想过要用 recycleview 来实现,不是不可以,是用 recycleview 的话,各种判断、计算偏移量太多了。

而且需求中要求只是文本,无需加载布局,所以为了节省时间就干脆自定义一个名为 HorizontalselectedView 的 View, 宽高无需自己计算, 只需在 onDraw() 方法里面把每个String 画出来, 然后监听滑动事件或者点击左右箭头的时候,重走onDraw()方法就可以了,难点在于 onDraw 的时候,每个 String 的坐标如何获得

控件特征

1、 中间箭头下面的文字(被选中的文字)颜色和字体和其他的不一样

2、 可以横向左右滑动,滑动过程当中,被选中的文字在变化

3、 点击左右箭头的时候也可以 实现滚动,从而改变被选中的文字

4、 可见区域内,显示的文字数是可以改变的

5、 左右滑动的时候有回弹选择效果

根据以上特征,就能得到我们所需要的自定义属性,如下:

在构造方法里面初始化画笔和属性:

重写onDraw()方法

所有的文字里面,被选中的文字是特殊的,他的大小和颜色不一样,所有我们先把他给画出来,关键点在于要测量文本的宽高,代码如下:

下面要做的是就是要遍历集合,把其他的文字给画出来,刚才也提到了,坐标是难点,我们看张图来理一理:

其实最巧妙的是得到图中所标注的 一个单元的长度anInt ,可见区域的长度除以可见个数就得到了 , 还有就是这个 n,给到数据源的时候,我是让数据源集合的长度除以2的,这个可以理解的。然后遍历集合的时候 就可以根据下面得到x的坐标: x=width/2+anInt*(i-n)-textWidth/2 ,这里面的 textWidth 我们默认他一样长了,但实际情况中,可能会出现三位数,四位数,三个字,四个字,所以在代码中,我是 获得被选中文字左右两面长度的平均值得到的

接下来就可以在 onDraw() 方法里面遍历了:

这样所得到的效果是把strings平铺在了控件上,其实已经有点样子了,下面就是进行滑动监听了。

触屏监听事件

触屏监听,自然而然就是要复写 onTouchEvent 方法了 , 这里的触屏事件还是比较简单的,先贴上代码:

奇怪的是,在这里面打 log,只有 down事件 触发,move 和 up 事件触发不了,这就要加上一行代码:

setClickable(true);//使可点击

down 的时候记录下 downX 坐标值,然后 move 时根据 scrollX 和 downX 的大小判断向左还是向右

从而当 scrollX -downX 的绝对值刚好等于 anInt 的时候,n 相应的 加1 或者 减一 , 再进行重绘,继而把此时的 scrollX 赋值给 downX;

这就实现了左右滑动,这个时候,整个文本向右或者向左 一个单元一个单元的移动,这显然不是我们要的效果,我们要的是,滑动的过程当中,文本就跟着手势在动,所以这里面肯定需要个偏移量 offSet;

offset = scrollX - downX;

当移动一个单元长度的时候再把 offset 归零就可以了;所以最终每个文本的x坐标为:

这样就基本实现需求了,需要注意的是有几个地方需要加上 n 的大小判断的,不能让他小于0了,或者大于集合长度了,防止越界

对外提供的一些方法

经验总结






请到「今天看啥」查看全文