Android 点击一个圆上的不同的扇形产生不同的事件


         在这里说明一点就是我上面的1,2,3,4是我自己定义的块。因为画扇形的时候api的是按照顺时针画的,而且起点是从第一块开始就是,先画黑色的

         最终达到的效果就是点击不同颜色的扇形,产生不同的事件。我给上面加边框的意思是这个边框和圆还有边框与圆之间的空白是同一个view,给新入门Android开发的同志来说一个知识点:view其实就是一个矩形。有时候我们用imageview显示不规则图片的时候觉得这个图片的形状是这个view的形状,其实不是的。

       下面来讲实现:

这个view一看就是用了自定义View  实现代码

 <pre name="code" class="java">public class FanshapedView extends View implements  OnTouchListener {
	//矩形,画扇形的时候需要传入的参数
	private RectF rectf;
	//此view的高度
	private int higth;
	//此view的宽度
	private int wide;
	
	private int absy;
	private int absx;
	//按下时的x,y的值
	private int downy;
	private int downx;
	//抬起时的x,y的值
	private int upx;
	private int upy;
	//用于计算点击处的角度
	private int tanx;
	private int tany;
	//中心点
	private int centerx;
	private int centery;
	//按下时x,y相对于中心点的坐标
	private int coordinatex;
	private int coordinatey;
	//扇形的半径
	private int radius;
	//监听器
	private FanshapedClicke fanshapedclicke;
	//扇形的弧度
	private  ArrayList<Integer>  arraydegrees;
	//扇形的颜色
	private  ArrayList<Integer>  arraycolor;
	public FanshapedView(Context context) {
		super(context);
		rectf = new RectF(0, 0, 500, 500);
	}

	@SuppressLint("ClickableViewAccessibility")
	public FanshapedView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.setOnTouchListener(this);
		arraydegrees=new ArrayList<Integer>();
		arraycolor=new ArrayList<Integer>();
		
		arraydegrees.add(45);
		arraycolor.add(Color.BLACK);
		
		arraydegrees.add(45);
		arraycolor.add(Color.BLUE);
		
		arraydegrees.add(90);
		arraycolor.add(Color.CYAN);
		
		arraydegrees.add(90);
		arraycolor.add(Color.DKGRAY);
		
		arraydegrees.add(60);
		arraycolor.add(Color.GREEN);
		
		arraydegrees.add(30);
		arraycolor.add(Color.LTGRAY);
	}
	
	
     /*这里多说一点,得到view的宽高,不能在构造函数中得到, 因为在构造函数中还不知道view的大小,所以得不到,在onMeasure与onLayout中都可以得到
      * getMeasuredHeight和getHeight两个都可以得到高度,至于有什么区别  百度一下吧。
      */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}
	@SuppressLint("DrawAllocation")
	@Override
	protected void onLayout(boolean changed, int left, int top, int right,int bottom) {
		super.onLayout(changed, left, top, right, bottom);
		if (changed) {
			//得到这个view的宽高;
			higth = this.getMeasuredHeight();
			wide = this.getMeasuredWidth();
			//算出中心点与半径
			centerx=radius=wide/2;
			centery=higth/2;
			//创建矩形
			rectf = new RectF(0, 0, higth, wide);
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// 创建画笔
		Paint p = new Paint();
		int degree=0;
		for (int i = 0; i < arraydegrees.size(); i++){
		// 设置红色
		p.setColor(arraycolor.get(i));
		// 画弧,第一个参数是RectF:该类是第二个参数是角度的开始,第三个参数是多少度,第四个参数是真的时候画扇形,是假的时候画弧线,第五个是画笔
		canvas.drawArc(rectf, degree, arraydegrees.get(i), true, p);
		degree=arraydegrees.get(i)+degree;
		}
	}
	@SuppressLint("ClickableViewAccessibility")
	@Override
	public boolean onTouch(View arg0, MotionEvent arg1) {
		switch (arg1.getAction()) {
		case MotionEvent.ACTION_DOWN:
		   //按下时候的x,y
           downx=(int) arg1.getX();
		   downy=(int) arg1.getY();
		   //计算按下的x,y与坐标中点的距离
		   absx=Math.abs(downx-centerx);
		   absy=Math.abs(downy-centery);
		   //用于计算正切值
		   tanx=Math.abs(downx-centerx); 
		   tany=Math.abs(downy-centery);
		   //按下时x,y相对于中心点的坐标
		   coordinatex=downx-centerx;
		   coordinatey=centery-downy;
			break;
		case MotionEvent.ACTION_UP:
			//抬起来时候的x,y
			upx=(int) arg1.getX();
			upy=(int) arg1.getY();
			//
			boolean t=((upx-downx)*(upx-downx)+(upy-downy)*(upy-downy))<25;
			int a=absx*absx	+absy*absy;
			if(a<radius*radius&&t){
			double jiaodu=getangle(tanx, tany, coordinatex, coordinatey);
			itemClicke(jiaodu);
			}
			break;
		case MotionEvent.ACTION_MOVE:
			break;
        case MotionEvent.ACTION_CANCEL:
			break;
		default:
			break;
		}
		return true;
	}
	
	/**
	 * 
	 * @param 用于计算正切值的x
	 * @param 用于计算正切值的y
	 * @param downx  downy 用于判断按下时候  在第几块
	 * @return 得到按下时候的角度
	 */
	protected double getangle(int x,int y,int downx,int downy) {
		double angle=(float) 0.0;
		if(downx>0&&downy<0){
			double c=(double)y/(double)x;
			double d=Math.toDegrees(Math.atan(c));
			angle=d;
		}else if(downx<=0&&downy<=0){
			double c=(double)x/(double)y;
			double d=Math.toDegrees(Math.atan(c));
			angle=d+90;
		}else if(downx<0&&downy>=0){
			double c=(double)y/(double)x;
			double d=Math.toDegrees(Math.atan(c));
			angle=180+d;
		}else{
			double c=(double)x/(double)y;
			double d=Math.toDegrees(Math.atan(c));
			angle=d+270;
		}
		return angle;
	}
	//添加监听事件
	protected void itemClicke(double jiaodu) {
		int jianji=(int)jiaodu;
		int b=0;
		int c=arraydegrees.get(0);
		System.out.println(jianji);
		for (int i = 0; i < arraydegrees.size(); i++) {
			if(jianji>b&&jianji<c){
				fanshapedclicke.itemClicke(i+1)	;
				return;
			}
			b=b+arraydegrees.get(i);
			c=b+arraydegrees.get(i+1);
		} 
	}
	//添加监听器
	public void setFanshapedClicke(FanshapedClicke fanshapedClicke){
		this.fanshapedclicke=fanshapedClicke;
	}
	//定义监听接口
	public interface  FanshapedClicke{
	public void itemClicke(int a) ;
	}
}

 整个工程的下载地址   
点击这个 


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值