android 自己动手画一个圆形菜单
来源:互联网 发布:阿里云域名申请 编辑:程序博客网 时间:2024/06/04 23:20
本文使用画笔Paint来自定义一个半圆形的菜单 如下图:
二、在onLayout(boolean changed, int left, int top, int right,int bottom)方法中可以获取到此view在屏幕上的上下左右坐标。通过x = right - left,y = bottom - top可计算出当前view的尺寸,为接下来画圆做准备。
三、初始化
1、由于屏幕尺寸的不同,所以导致当前view的尺寸是不定的,只能通过计算来获取当前圆形菜单的半径(此计算方法是我经过多尺寸手机的实际测试计算出来的),这里得到的不是整个圆,而是大半圆,所以圆点坐标往X轴正方向移动了大概1/3
mPaint.setColor(666885);mPaint.setStrokeWidth(6);setBackgroundResource(R.drawable.bg);dvlue = 0;// 做适配屏幕处理if (x >= y) {minSize = y;dvlue = x - y;} else {minSize = x;dvlue = y - x;}if (dvlue > 180) {mPointX = x / 3 * 2 + minSize / 10;mPointY = y / 2 + minSize / 20;mRadius = minSize / 2 + minSize / 20;} else if (dvlue > 90) {type = 2;mPointX = x / 3 * 2 + minSize / 30;mPointY = y / 2 + minSize / 30;mRadius = minSize / 2 - minSize / 60;} else {type = 3;mPointX = x / 3 * 2;mPointY = y / 2 + minSize / 30;mRadius = minSize / 2 - minSize / 12;}if (mRadius * 2 + (minSize / 4 / 2) > y) {mRadius = mRadius - (mRadius * 2 + minSize / 4 / 2 - y);}
2、初始化每个控件
a、先创建控件实体类Stone
class Stone {// 图片Bitmap bitmap;// 角度int angle;// x坐标float x;// y坐标float y;// 是否可见boolean isVisible = true;}
b、初始化每个控件angle是菜单的起始角度,mDegreeDelta是每个控件之间的间隔角度STONE_COUNT是菜单中选项的个数,通过计算当前view的尺寸来决定每个控件的大小,这步能够得到每个控件与X轴的角度,下一步通过半径与这个角度来得到控件在圆形菜单上的坐标
private void initStones() {mStones = new Stone[STONE_COUNT];mStones2 = new Stone[STONE_COUNT];Stone stone;Stone stone2;int angle = 130;mDegreeDelta = 43;for (int index = 0; index < STONE_COUNT; index++) {stone = new Stone();stone2 = new Stone();if (index != 0) {stone.angle = angle;angle += mDegreeDelta;} elsestone.angle = 0;Bitmap b = BitmapFactory.decodeResource(getResources(), rec[index]);float width = 0;if (index != 0) {width = (minSize / 4 - type * 5) / (float) b.getWidth();} else {width = (minSize / 2 - type * 15) / (float) b.getWidth();}if (width <= 0) {width = 1;}Matrix matrix = new Matrix();matrix.postScale(width, width);stone.bitmap = Bitmap.createBitmap(b, 0, 0, b.getWidth(),b.getHeight(), matrix, true);mStones[index] = stone;width += 0.1;Matrix matrix2 = new Matrix();matrix2.postScale(width, width);stone2.bitmap = Bitmap.createBitmap(b, 0, 0, b.getWidth(),b.getHeight(), matrix2, true);mStones2[index] = stone2;}}
C、计算每个控件的坐标,知道了半径mRadius远点坐标mPointX、mPointY以及每个控件与X轴的角度,这样就构成了一个直角三角形,通过正弦定理和余弦定理就能确定控件距离X、Y轴的距离,然后加上圆点坐标,就得到了每个控件的坐标。
private void computeCoordinates() {Stone stone;for (int index = 0; index < STONE_COUNT; index++) {stone = mStones[index];if (index != 0) {stone.x = mPointX+ (float) (mRadius * Math.cos(stone.angle * Math.PI/ 180));stone.y = mPointY+ (float) (mRadius * Math.sin(stone.angle * Math.PI/ 180));} else {if (dvlue > 180) {stone.x = mPointX - minSize / 15;stone.y = mPointY + minSize / 20;} else if (dvlue > 90) {stone.x = mPointX;stone.y = mPointY + minSize / 20;} else {stone.x = mPointX + minSize / 18;stone.y = mPointY + minSize / 20;}}ViewParam vp = new ViewParam();vp.startX = (int) (stone.x - stone.bitmap.getWidth() / 2);vp.endX = (int) (stone.x + stone.bitmap.getWidth() / 2);vp.startY = (int) (stone.y - stone.bitmap.getHeight() / 2);vp.endY = (int) (stone.y + stone.bitmap.getHeight() / 2);vl.add(vp);}
四、在onDraw(Canvas canvas)方法中使用canvas.drawPoint、canvas.drawBitmap画出控件
@Overridepublic void onDraw(Canvas canvas) {/*** 画虚线*/for (int i = 0; i < 360; i = i + 4) {mPaint.setAlpha(alp);if (i < 180) {if (alp < 256 - malp)alp += malp * 5;if (alp > 180)alp = 180;} else {if (alp > malp)alp -= malp * 5;if (alp < 0)alp = 0;}canvas.drawPoint(mPointX + (float) (mRadius * Math.cos(i * Math.PI / 180)),mPointY + (float) (mRadius * Math.sin(i * Math.PI / 180)),mPaint);}/*** 画控件*/for (int index = 0; index < STONE_COUNT; index++) {if (!mStones[index].isVisible)continue;if (selectItem == currItem && selectItem >= 0&& selectItem == index) {// 按下transBitmap = mStones[index].bitmap;mStones[index].bitmap = mStones2[index].bitmap;mStones2[index].bitmap = transBitmap;isNarrow = true;} else if (currItem >= 0 && currItem != selectItem&& currItem == index && isNarrow) {// 抬起transBitmap = mStones[index].bitmap;mStones[index].bitmap = mStones2[index].bitmap;mStones2[index].bitmap = transBitmap;currItem = -1;isNarrow = false;}drawCenter(canvas, mStones[index].bitmap, mStones[index].x,mStones[index].y);}if (selectItem < 0 && currItem >= 0 && !isNarrow) {selectItem = -1;currItem = -1;isNarrow = false;}}
五、添加点击事件
在dispatchTouchEvent(MotionEvent event)中处理事件
1、在MotionEvent.ACTION_DOWN:中记录当前点击的坐标及控件状态
2、在MotionEvent.ACTION_UP中处理各种情况
3、通过setOnMenuClickListener(MainMeunClickListener m)回调方法将点击事件反馈出去
注:由于画出来的控件是没有点击事件的,所以只能自定义点击事件,大概思路:已知当前所有控件的坐标位置与每个控件的大小,便可知道此控件的面积所在的坐标范围,当有点击事件的时候,判断是否在控件的面积之内,便可实现点击效果。
- android 自己动手画一个圆形菜单
- Android 圆形头像 自己动手
- Android一个漂亮的圆形菜单
- Android 仿酷点圆形菜单
- Android 圆形滑动菜单
- Android---圆形菜单
- Android圆形旋转菜单
- Android自定义圆形菜单
- Android 圆形旋转菜单
- android 高仿圆形菜单
- Android CircleMenu 圆形旋转菜单
- Android之仿优酷圆形菜单
- Android 圆形旋转菜单【转】
- 自定义一个简单的圆形菜单
- d3.js 画圆形菜单
- android自定义控件(一):写一个圆形菜单的Layout
- Android 实现圆形转盘菜单(CirCleMenu)
- Android WheelMenu圆形菜单,巧妙实现
- 三分搜索 (算法设计与分析课后习题)
- Elasticsearch 标准分词和ik分词的差别
- 数据挖掘十大经典算法(8) kNN: k-nearest neighbor classification
- Unity曝露变量的显示与隐藏
- WPF ListView控件设置奇偶行背景色交替变换以及ListViewItem鼠标悬停动画
- android 自己动手画一个圆形菜单
- PHP 线程,进程和并发
- TreeMap源码导读
- 2014年个人工作总结(补发)
- 数据挖掘十大经典算法(9) 朴素贝叶斯分类器 Naive Bayes
- 理解Fragment生命周期
- Android开发性能优化大总结
- POJ-1284-Primitive Roots 解题报告
- Android 自定义 ViewPager 打造千变万化的图片切换效果