Android圆盘菜单(修改了网络上现有的demo总是显示第一个的bug,

导语:最近项目中要用的圆盘菜单,,在网上找了一圈发现现有的demo都不能拿过来直接用因为都是太基础了,所以自己在原有的基础上修改了下,增加了点击事件以及修正了滑动后总是从第一个开始绘图的bug。

package chroya.demo.roundspin;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.view.MotionEvent;import android.view.View;import android.widget.Toast;/** * 圆盘式的view * @author chroya * */public class RoundSpinView extends View {private Paint mPaint = new Paint();private BigStone[] mStones;private static final int STONE_COUNT = 21;private int mPointX=0, mPointY=0;private int mRadius = 0;private int mDegreeDelta;private boolean isAllowed = false;private boolean isMove = false;private BigStone currentbstone = null;public RoundSpinView(Context context, int px, int py, int radius) {super(context);mPaint.setColor(Color.RED);mPaint.setStrokeWidth(2);setBackgroundResource(R.drawable.menubkground);mPointX = px;mPointY = py;mRadius = radius;setupStones();computeCoordinates();}/** * 初始化 */private void setupStones() {mStones = new BigStone[STONE_COUNT];BigStone stone;int angle = 0;mDegreeDelta = 360/STONE_COUNT;for(int index=0; index<STONE_COUNT; index++) {stone = new BigStone();stone.index = index;stone.content = index + "";stone.angle = angle;stone.bitmap = drawNumAtBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.icon),index);//增加点击事件stone.action = new ActionEvent(){@Overridepublic void action(BigStone stone) {Toast.makeText(RoundSpinView.this.getContext(), "你点击了我 ! " + stone.content, Toast.LENGTH_SHORT).show();}};angle += mDegreeDelta;mStones[index] = stone;}}/** * 重新计算每一个元素的坐标位置 * @param x * @param y */private void resetStonesAngle(float x, float y) {int angle = computeCurrentAngle(x, y);for(int index=0; index<STONE_COUNT; index++) {//从下标为0的开始for(BigStone bs : mStones){if(bs.index == index){bs.angle = angle;break;}}angle += mDegreeDelta;}}private void computeCoordinates() {for(BigStone stone : mStones) {stone.x = mPointX+ (float)(mRadius * Math.cos(stone.angle*Math.PI/180));stone.y = mPointY+ (float)(mRadius * Math.sin(stone.angle*Math.PI/180));}}/** * 计算手指划过的线性距离 * @param x * @param y * @return */private int computeCurrentAngle(float x, float y) {float distance = (float)Math.sqrt(((x-mPointX)*(x-mPointX) + (y-mPointY)*(y-mPointY)));int degree = (int)(Math.acos((x-mPointX)/distance)*180/Math.PI);if(y < mPointY) {degree = -degree;}return degree;}@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {if(event.getAction() == MotionEvent.ACTION_DOWN){isMove = false;int index = 0;float min = 320;//求出点击坐标X值与那么元素的坐标位置X值最为接近for(BigStone bs : mStones){if(bs.x >= 0 && bs.x <= 320 && min >= Math.max(bs.x, event.getX()) – Math.min(bs.x, event.getX())){min = Math.max(bs.x, event.getX()) – Math.min(bs.x, event.getX());index = bs.index;}}//或者该元素内容for(BigStone bs : mStones){if(bs.index == index){currentbstone = bs;break;}}//判断Y值是否也为最接近(可根据自己情况是否增加这段逻辑)if(currentbstone.y >= 0 && currentbstone.y <= 430 && 80 >= Math.max(currentbstone.y, event.getY()) – Math.min(currentbstone.y, event.getY())){isAllowed = true;if(index > 0){for(BigStone bs : mStones){if(bs.index >= index){bs.index = bs.index – index;}else{bs.index += STONE_COUNT – index;}}}}else{isAllowed = false;}}if(event.getAction() == MotionEvent.ACTION_MOVE && isAllowed){isMove = true;resetStonesAngle(event.getX(), event.getY());computeCoordinates();invalidate();}if(event.getAction() == MotionEvent.ACTION_UP && isAllowed){if(!isMove)currentbstone.action.action(currentbstone);}return true;}@Overridepublic void onDraw(Canvas canvas) {canvas.drawPoint(mPointX, mPointY, mPaint);for(int index=0; index<STONE_COUNT; index++) {for(BigStone bs : mStones){if(bs.index == index){drawInCenter(canvas, bs.bitmap, bs.x, bs.y);canvas.drawLine(mPointX, mPointY, bs.x, bs.y, mPaint);break;}}}}/** * 把中心点放到中心处 * @param canvas * @param bitmap * @param left * @param top */void drawInCenter(Canvas canvas, Bitmap bitmap, float left, float top) {canvas.drawPoint(left, top, mPaint);canvas.drawBitmap(bitmap, left-bitmap.getWidth()/2, top-bitmap.getHeight()/2, null);}interface ActionEvent{public void action(BigStone stone);}class BigStone {int index;//图片Bitmap bitmap;//角度int angle;//x坐标float x;//y坐标float y;String content;ActionEvent action;}public static Bitmap drawNumAtBitmap(Bitmap bitmap, int num) {int x = bitmap.getWidth();int y = bitmap.getHeight();Bitmap newbit = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(newbit);Paint paint = new Paint();canvas.drawBitmap(bitmap, 0, 0, paint);paint.setColor(Color.RED);paint.setTextSize(20);if (num >= 10) {canvas.drawText(num + "", 9, 25, paint);} else {canvas.drawText(num + "", 15, 25, paint);}canvas.save(Canvas.ALL_SAVE_FLAG);canvas.restore();bitmap.recycle();return newbit;}}package chroya.demo.roundspin;import android.app.Activity;import android.os.Bundle;public class Main extends Activity {/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(new RoundSpinView(getApplicationContext(), 160, 430, 240));}}我还不会上传源码…研究下上传上来~!

三亚呀——赴一个蓝天碧海。

Android圆盘菜单(修改了网络上现有的demo总是显示第一个的bug,

相关文章:

你感兴趣的文章:

标签云: