`
chroya
  • 浏览: 656654 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Android简单的圆盘形菜单

阅读更多

      今天偶然看到一个圆盘形的菜单,还可以转动,感觉挺有意思,然后想了想,做了个简单的效果。
      思路是这样的,定一个原点和一个半径,圆的四周均匀分布每个菜单。为了方便计算,菜单的坐标用度数表示,然后转化为极坐标计算。
      定某个点为起始点,根据总菜单数确定每个点增加的度数,然后依次确定每个点的度数,也就确定了坐标。

 

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;
	}
}

       代码里注释也很清楚。STONE_COUNT表示菜单的数目,可以设置为1到7,更大的数字需要图片支持,我只放了7张图片。

       如果触摸的点不在圆周上,会自动计算出点到圆心的直线跟圆的交点,然后映射上去。

       5个菜单的效果,画了线的:

       6个菜单的效果:

          Ok,代码也贡献出来。

11
0
分享到:
评论
15 楼 weich_java 2013-05-14  
http://blog.csdn.net/weich_java/article/details/8924700
14 楼 weich_java 2013-05-14  
chroya 写道
gmxstar 写道
Reizsoon 写道
琼露露 写道
怎么监听图片选中呢,想知道选中图片然后跳转到其他页面怎么做

同样的问题,求楼主赐教啊

同求啊


监听touch事件,取得当前按下的点坐标,判断坐标在哪个图片的范围之内即可。

去我的csdn空间,我修改总是从第一个绘制的bug并增加了click事件。
13 楼 weich_java 2013-05-14  
廖星辰gogo 写道
楼主请问为何按下去旋转都是menu1的位置?

去我的csdn空间,我修改总是从第一个绘制的bug并增加了click事件。
12 楼 weich_java 2013-05-14  
琼露露 写道
怎么监听图片选中呢,想知道选中图片然后跳转到其他页面怎么做
去我的csdn空间,我修改总是从第一个绘制的bug并增加了click事件。
11 楼 廖星辰gogo 2012-10-23  
楼主请问为何按下去旋转都是menu1的位置?
10 楼 chroya 2012-08-22  
eternallove1314520 写道
楼主你好  可以给我一份这个的代码吗?我的QQ邮箱306219744@qq.com  谢谢 最好是添加了图片的监听事件的 谢谢了

博文的最后已经把代码放出来了
9 楼 eternallove1314520 2012-08-20  
楼主你好  可以给我一份这个的代码吗?我的QQ邮箱306219744@qq.com  谢谢 最好是添加了图片的监听事件的 谢谢了
8 楼 flyingsir_zw 2012-08-14  
 
7 楼 shinsoft 2012-05-28  
感謝樓主,偉大的人
6 楼 alienshooter01 2012-04-16  
楼主好伟大 哈哈
5 楼 chroya 2011-12-31  
gmxstar 写道
Reizsoon 写道
琼露露 写道
怎么监听图片选中呢,想知道选中图片然后跳转到其他页面怎么做

同样的问题,求楼主赐教啊

同求啊


监听touch事件,取得当前按下的点坐标,判断坐标在哪个图片的范围之内即可。
4 楼 gmxstar 2011-12-22  
Reizsoon 写道
琼露露 写道
怎么监听图片选中呢,想知道选中图片然后跳转到其他页面怎么做

同样的问题,求楼主赐教啊

同求啊
3 楼 Reizsoon 2011-12-14  
琼露露 写道
怎么监听图片选中呢,想知道选中图片然后跳转到其他页面怎么做

同样的问题,求楼主赐教啊
2 楼 琼露露 2011-03-15  
怎么监听图片选中呢,想知道选中图片然后跳转到其他页面怎么做
1 楼 Coding.Ghost 2010-12-12  
学习中..正需要这方面的资料..

相关推荐

Global site tag (gtag.js) - Google Analytics