android圆盘菜单效果

public class TurnplateView extends View implements OnTouchListener {

 private OnTurnplateListener onTurnplateListener;

 public void setOnTurnplateListener(OnTurnplateListener onTurnplateListener) {
  this.onTurnplateListener = onTurnplateListener;
 }

 /**
  * 画笔:点、线
  */
 private Paint mPaint = new Paint();
 /**
  * 画笔:圆
  */
 private Paint paintCircle = new Paint();
 /**
  * 图标列表
  */
 private Bitmap[] icons = new Bitmap[10];
 /** 菜单背景 */
 private Bitmap turnPlateBg;
 /**
  * point列表
  */
 private Point[] points;
 /**
  * 数目
  */
 private static final int PONIT_NUM = 3;

 /**
  * 圆心坐标
  */
 private int mPointX = 0, mPointY = 0;
 /**
  * 半径
  */
 private int mRadius = 0;
 /**
  * 每两个点间隔的角度
  */
 private int mDegreeDelta;
 /**
  * 每次转动的角度差
  */
 private int tempDegree = 0;
 /**
  * 选中的图标标识
  */
 private int curChooseIndex = -1;
 private Matrix mMatrix = new Matrix();
 // 每个菜单的宽和高
 private int itemWidth, itemHeight;

 public TurnplateView(Context context, int px, int py, int radius) {
  super(context);
  mPaint.setColor(Color.RED);
  mPaint.setStrokeWidth(2);
  paintCircle.setAntiAlias(true);
  paintCircle.setColor(Color.WHITE);

  mPointX = px;
  mPointY = py;
  mRadius = radius;

  itemWidth = radius * 2 / 3;
  itemHeight = radius * 2 / 3;

  loadIcons();

  initPoints();
  computeCoordinates();
 }

 public void loadBitmaps(int key, Drawable d) {
  Bitmap bitmap = Bitmap.createBitmap(itemWidth, itemHeight,
    Bitmap.Config.ARGB_8888);
  Canvas canvas = new Canvas(bitmap);
  d.setBounds(0, 0, itemWidth, itemHeight);
  d.draw(canvas);
  icons[key] = bitmap;
  turnPlateBg = BitmapUtil.getResizeBitmap(getContext(),
    R.drawable.turnplate_bg, mRadius * 2, mRadius * 2);
 }

 public void loadIcons() {
  Resources r = getResources();
  loadBitmaps(0, r.getDrawable(R.drawable.tools_ad_icon));
  loadBitmaps(1, r.getDrawable(R.drawable.tools_huangli_icon));
  loadBitmaps(2, r.getDrawable(R.drawable.tools_preview));
 }

 public void setPoints(Point[] points) {
  this.points = points;
 }

 /**
  * 
  * 方法名:initPoints 功能:初始化每个点
  */

 private void initPoints() {
  points = new Point[PONIT_NUM];
  Point point;
  int angle = 0;
  mDegreeDelta = 360 / PONIT_NUM;

  for (int index = 0; index < PONIT_NUM; index++) {
   point = new Point();
   point.angle = angle;
   angle += mDegreeDelta;
   point.bitmap = icons[index];
   point.flag = index;
   points[index] = point;
   switch (index) {
   case 0:
    points[index].intent = new Intent(getContext(),
      IndexActivity.class);
    break;
   case 1:
    points[index].intent = new Intent(getContext(),
      CalendarActivity.class);
    break;
   case 2:
    points[index].intent = new Intent(getContext(),
      AnimDemoActivity.class);
    break;
   }

  }
 }

 /**
  * 
  * 方法名:resetPointAngle 功能:重新计算每个点的角度 参数:
  * 
  * @param x
  * @param y
  */
 private void resetPointAngle(float x, float y) {
  int degree = computeMigrationAngle(x, y);
  for (int index = 0; index < PONIT_NUM; index++) {
   points[index].angle += degree;
   if (points[index].angle > 360) {
    points[index].angle -= 360;
   } else if (points[index].angle < 0) {
    points[index].angle += 360;
   }

  }
 }

 /**
  * 
  * 方法名:computeCoordinates 功能:计算每个点的坐标
  */
 private void computeCoordinates() {
  Point point;
  for (int index = 0; index < PONIT_NUM; index++) {
   point = points[index];
   point.x = mPointX
     + (float) (mRadius * Math.cos(point.angle * Math.PI / 180));
   point.y = mPointY
     + (float) (mRadius * Math.sin(point.angle * Math.PI / 180));
   point.x_c = mPointX + (point.x - mPointX) / 2;
   point.y_c = mPointY + (point.y - mPointY) / 2;
   // Log.e(TAG, point.angle+"");
  }
 }

 /**
  * 
  * 方法名:computeMigrationAngle 功能:计算偏移角度 参数:
  * 
  * @param x
  * @param y
  */
 private int computeMigrationAngle(float x, float y) {
  int a = 0;
  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;
  }
  if (tempDegree != 0) {
   a = degree - tempDegree;
  }
  tempDegree = degree;
  return a;
 }

 /**
  * 
  * 方法名:computeCurrentDistance 功能:计算触摸的位置与各个元点的距离 参数:
  * 
  * @param x
  * @param y
  */
 private void computeCurrentDistance(float x, float y) {
  for (Point point : points) {
   float distance = (float) Math
     .sqrt(((x - point.x) * (x - point.x) + (y - point.y)
       * (y - point.y)));
   if (distance < 31) {
    curChooseIndex = point.flag;
    break;
   } else {
    curChooseIndex = 999;
   }
  }
 }

 private void switchScreen(MotionEvent event) {
  computeCurrentDistance(event.getX(), event.getY());
  onTurnplateListener.onPointTouch(curChooseIndex);

 }

 @Override
 public boolean dispatchTouchEvent(MotionEvent event) {
  int action = event.getAction();
  switch (action) {
  case MotionEvent.ACTION_DOWN:
   break;
  case MotionEvent.ACTION_MOVE:
   resetPointAngle(event.getX(), event.getY());
   computeCoordinates();
   invalidate();
   break;
  case MotionEvent.ACTION_UP:
   switchScreen(event);
   tempDegree = 0;
   invalidate();
   break;
  case MotionEvent.ACTION_CANCEL:
   // 系统在运行到一定程度下无法继续响应你的后续动作时会产生此事件。
   // 一般仅在代码中将其视为异常分支情况处理
   break;
  }
  return true;
 }

 @Override
 public void onDraw(Canvas canvas) {
  // canvas.drawCircle(mPointX, mPointY, mRadius, paintCircle);
  canvas.drawBitmap(turnPlateBg, mPointX - mRadius, mPointY - mRadius,
    paintCircle);
  canvas.drawPoint(mPointX, mPointY, mPaint);

  for (int index = 0; index < PONIT_NUM; index++) {
   canvas.drawPoint(points[index].x_c, points[index].y_c, mPaint);
   drawInCenter(canvas, points[index].bitmap, points[index].x,
     points[index].y, points[index].flag);
  }

 }

 /**
  * 
  * 方法名:drawInCenter 功能:把点放到图片中心处 参数:
  * 
  * @param canvas
  * @param bitmap
  * @param left
  * @param top
  */
 void drawInCenter(Canvas canvas, Bitmap bitmap, float left, float top,
   int flag) {
  canvas.drawPoint(left, top, mPaint);
  if (curChooseIndex == flag) {
   mMatrix.setScale(70f / bitmap.getWidth(), 70f / bitmap.getHeight());
   mMatrix.postTranslate(left - 35, top - 35);
   canvas.drawBitmap(bitmap, mMatrix, null);
  } else {
   canvas.drawBitmap(bitmap, left - bitmap.getWidth() / 2, top
     - bitmap.getHeight() / 2, null);
  }

 }

 class Point {

  /**
   * 位置标识
   */
  int flag;
  /**
   * 图片
   */
  Bitmap bitmap;

  /**
   * 角度
   */
  int angle;

  /**
   * x坐标
   */
  float x;

  /**
   * y坐标
   */
  float y;

  /**
   * 点与圆心的中心x坐标
   */
  float x_c;
  /**
   * 点与圆心的中心y坐标
   */
  float y_c;
  // 保存的数据
  Intent intent;
 }

 public static interface OnTurnplateListener {

  public void onPointTouch(int flag);

 }

 @Override
 public boolean onTouch(View arg0, MotionEvent arg1) {
  return false;
 }

 public Intent getCurIntent(int flag) {
  if (flag >= 0 && flag < points.length) {
   Point curPoint = points[flag];
   return curPoint.intent;
  } else {
   return null;
  }
 }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值