专栏名称: 郭霖
Android技术分享平台,每天都有优质技术文章推送。你还可以向公众号投稿,将自己总结的技术心得分享给大家。
目录
相关文章推荐
stormzhang  ·  维权成功! ·  6 天前  
鸿洋  ·  Android 15 正式发布到 AOSP ... ·  1 周前  
stormzhang  ·  国庆前,2 件大事 ·  1 周前  
51好读  ›  专栏  ›  郭霖

RoundMenuView一一自定义扇形菜单控件

郭霖  · 公众号  · android  · 2017-04-10 08:00

正文

今日科技快讯

今日起,滴滴快车将引入“分时计价”模式和新计费标准,非高峰时段出行价格有优惠。同时,将起步价调从10元整为13元。“分时计价”是指,通过下调里程费,10点至17点的订单特别是中长距离订单的费用将有较为明显的下降。早晚高峰期和夜间的时长费则略涨。

作者简介

大家早上好,新的一周开始啦!

本篇来自 凶残的程序员 的投稿,分享了一个扇形的菜单控件,希望大家喜欢!

凶残的程序员 的博客地址:

http://blog.csdn.net/qian520ao

正文

第一次写博客,不知道什么姿势才能显示出一副好像很老练的样子。老大让写一个菜单栏控件,借鉴了Idtk自定义view,站在巨人的肩上思路是豁然开朗。

效果图

使用方式

开始绘制(分2种情况,触摸|未触摸)

①:未触摸显示解刨

展示的图形分为4个模块,标签层rectFLabl、绘制bmp的rectF、白金层rectFGold(因为不会拼写银这个单词白金高大上啊),对应不同的半径如上图所示。代码中rectF 表示未触摸层,rectFF表示触摸弹出层,下面会讲解。

②:绘制 

xfermode详情跳转

http://blog.csdn.net/harvic880925/article/details/51264653

③:触摸touch显示解刨

与触摸层有点类似,标签层改为阴影部分,原本绘制bmp区域现在绘制文字。不过所有的半径变大。绘制的方法和上面的神似,这里就不举栗说出了。

④:开始绘制文字

绘制文字和bmp首先要先复习一下数学公式。再此我希望我的数学老师们都把学费还给我,毕竟我知识也还给你们了啊。

x=Math.sin(2∗PI/360∗angle)∗r

y=Math.cos(2∗PI/360∗angle)∗r

上面公式中,2*PI/360*angle,即求angle的弧度。

Math.sin(x) x 的正玄值。返回值在 -1.0 到 1.0 之间;

Math.cos(x) x 的余弦值。返回的是 -1.0 到 1.0 之间的数;

这两个函数中的X 都是指的“弧度”而非“角度”,而我们可以用 Math.toRadians(angle)求出当前的弧度,所以最终我们可以用 
 x=Math.sin(Math.toRadians(angle))∗r 来获取当前角度对应的半径所在的的x轴坐标,y轴亦可。

我们先绘制文字,如上图的9个文字。“不辣,川菜一点都不辣” :

绘制文字 和 绘制模块RECTF 有一点区别,模块是一个角度一个角度绘制,为了用户体验。但是绘制文字选择的是根据 animatedValue(从0到最大显示角度所返回的animation.getAnimatedValue值) 的角度去处理不同区域的文字。

举个栗子:如果当前有3个模块共180°,那么 animatedValue==60° 的时候我们绘制第一个模块的文字, animatedValue<120度 的时候我们还是绘制第一个模块的文字。

⑤:绘制bitmap

绘制之前首先我们要得到 bitmap 最大width/height,再获取 bitmap 中心点。获取中心点上面的栗子已经有说明了,那么我们现在着重获取 bitmap 的最大宽高。然后得到两者的较小值即可设定为 bitmap 区域。

灵魂画家。。。

⑥:绘制原点旋转的bitmap

我们将bitmap挪动到屏幕中心点,即bitmap中心点==绘制中心点。再根据当前animatedValue的角度进行旋转。

了解更多的matrix

http://www.gcssloop.com/customview/Matrix_Basic

OnTouch处理

首先,我们绘图 onDraw() 的时候将画板canvas移动到中心点,所以我们这样处理坐标点

float x = event.getX() - (mWidth / 2);

float y = event.getY()- (mHeight / 2); 

第二步我们要求出触摸的角度,因为Android里面坐标系与我们数学上的不同,android由第4 - 3 - 2 -1 象限开始绘制角度。

获取角度的方法:Math.toDegrees(Math.atan(y/x));

但是当 x<0 的时候,,求出的角度实为 [0°,-90°) ,此时我们给它掰正。当 x<0,角度就+180°。

求出触摸的角度之后我们再算出触摸的半径,这样子就可以判断当前是否触摸到了我们所绘制的各个模块上。

另外,老大对 onTouch 触摸的时候有个提议,那就是触摸中心bmp菜单之后不松手(此时 animator显示),然后滑动屏幕选择对应的模块后松手,一气呵成。也就是 一个ACTION_DOWN 和 一个ACTION_UP,中间 N个ACTION_MOVE,这没关系,有需求我们就去做是吧。

没关系,我们在当前Activity做一下处理,在move和up事件中不处理,传给我们自定义view,传入的event.getRawX() - pieLocation[0]就可以视为是在我们MenuChart里面对应的坐标点了。[可以试一下点击小二,来份菜单btn的时候手指不松开移动到展示开的模块。]

结束语

因为毕竟新手上路,所以可能会存在某些问题,不过感言应该就是动手写东西的确比想象中的难,不积跬步无以至千里。有什么不正确的地方,希望大家指正。

项目地址:

https://github.com/qdxxxx/MenuChart

更多

每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。

如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。

欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号: