Android简单的圆盘形菜单

今天偶然看到一个圆盘形的菜单,还可以转动,感觉挺有意思,然后想了想,做了个简单的效果。
思路是这样的,定一个原点和一个半径,圆的四周均匀分布每个菜单。为了方便计算,菜单的坐标用度数表示,然后转化为极坐标计算。
定某个点为起始点,根据总菜单数确定每个点增加的度数,然后依次确定每个点的度数,也就确定了坐标。
Java代码
[b]
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.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
* 圆盘式的view
* @author chroya
*
*/
public class RoundSpinView extends View {
private Paint mPaint = new Paint();

//stone列表
private BigStone[] mStones;
//数目
private static final int STONE_COUNT = 6;

//圆心坐标
private int mPointX=0, mPointY=0;
//半径
private int mRadius = 0;
//每两个点间隔的角度
private int mDegreeDelta;

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.angle = angle;
stone.bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.menu1+index);
angle += mDegreeDelta;

mStones[index] = stone;
}
}

/**
* 重新计算每个点的角度
*/
private void resetStonesAngle(float x, float y) {
int angle = computeCurrentAngle(x, y);
Log.d("RoundSpinView", "angle:"+angle);
for(int index=0; index<STONE_COUNT; index++) {
mStones[index].angle = angle;
angle += mDegreeDelta;
}
}

/**
* 计算每个点的坐标
*/
private void computeCoordinates() {
BigStone stone;
for(int index=0; index<STONE_COUNT; index++) {
stone = mStones[index];
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;
}

Log.d("RoundSpinView", "x:"+x+",y:"+y+",degree:"+degree);
return degree;
}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
resetStonesAngle(event.getX(), event.getY());
computeCoordinates();
invalidate();
return true;
}

@Override
public void onDraw(Canvas canvas) {
canvas.drawPoint(mPointX, mPointY, mPaint);

for(int index=0; index<STONE_COUNT; index++) {
if(!mStones[index].isVisible) continue;
drawInCenter(canvas, mStones[index].bitmap, mStones[index].x, mStones[index].y);
//不想有红线,就注掉下面这句
// canvas.drawLine(mPointX, mPointY, mStones[index].x, mStones[index].y, mPaint);
}
}

/**
* 把中心点放到中心处
* @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);
}

class BigStone {

//图片
Bitmap bitmap;

//角度
int angle;

//x坐标
float x;

//y坐标
float y;

//是否可见
boolean isVisible = true;
}
}
[/b]
代码里注释也很清楚。STONE_COUNT表示菜单的数目,可以设置为1到7,更大的数字需要图片支持,我只放了7张图片。
如果触摸的点不在圆周上,会自动计算出点到圆心的直线跟圆的交点,然后映射上去。
5个菜单的效果,画了线的:
[img]http://dl.iteye.com/upload/attachment/0069/6627/4fff8f61-bc1e-3f51-9a56-51f5a1e862ef.png[/img]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值