![]()
![]()
![]()
上面就是几张预览图!代码在最底下
主要就两个步骤,画图、监听点击
1、整个控件基本上是一步步画出来的,重写onDraw方法开始for循环画扇形出来,画扇形的时候同时画扇形内的图标,扇形画完了之后画中心圆按钮,中心画了圆之后吧OK按钮画上。
2、重写onTouch方法监听手指触发的位置,根据按下的位置确定按钮在哪个扇形的范围上,然后重绘一下onDraw把按下的灰色背景绘制出来。难点在于如何确定按下的位置是否处于扇形范围,换了好几种方案,奈何数学不好,最后选了现在使用的方案。
package com.imxiaoyu.common.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class RoundMenuView extends View {
private int coreX;
private int coreY;
private List<RoundMenu> roundMenus;
private boolean isCoreMenu = false;
private int coreMenuColor;
private int coreMenuStrokeColor;
private int coreMenuStrokeSize;
private int coreMenuSelectColor;
private Bitmap coreBitmap;
private OnClickListener onCoreClickListener;
private float deviationDegree;
private int onClickState = -2;
private int roundRadius;
private double radiusDistance;
private long touchTime;
public RoundMenuView(Context context) {
super(context);
}
public RoundMenuView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundMenuView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
coreX = getWidth() / 2;
coreY = getHeight() / 2;
roundRadius = (int) (getWidth()/2 * radiusDistance);
RectF rect = new RectF(0, 0, getWidth(), getHeight());
if (roundMenus != null && roundMenus.size() > 0) {
float sweepAngle = 360 / roundMenus.size();
deviationDegree = sweepAngle / 2;
for (int i = 0; i < roundMenus.size(); i++) {
RoundMenu roundMenu = roundMenus.get(i);
Paint paint = new Paint();
paint.setAntiAlias(true);
if (onClickState == i) {
paint.setColor(roundMenu.selectSolidColor);
} else {
paint.setColor(roundMenu.solidColor);
}
canvas.drawArc(rect, deviationDegree + (i * sweepAngle), sweepAngle, true, paint);
paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(roundMenu.strokeSize);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(roundMenu.strokeColor);
canvas.drawArc(rect, deviationDegree + (i * sweepAngle), sweepAngle, roundMenu.useCenter, paint);
Matrix matrix = new Matrix();
matrix.postTranslate((float) ((coreX + getWidth() / 2 * roundMenu.iconDistance) - (roundMenu.icon.getWidth() / 2)), coreY - (roundMenu.icon.getHeight() / 2));
matrix.postRotate(((i + 1) * sweepAngle), coreX, coreY);
canvas.drawBitmap(roundMenu.icon, matrix, null);
}
}
if (isCoreMenu) {
RectF rect1 = new RectF(coreX - roundRadius, coreY - roundRadius, coreX + roundRadius, coreY + roundRadius);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(coreMenuStrokeSize);
if (onClickState == -1) {
paint.setColor(coreMenuSelectColor);
} else {
paint.setColor(coreMenuColor);
}
canvas.drawArc(rect1, 0, 360, true, paint);
paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(coreMenuStrokeSize);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(coreMenuStrokeColor);
canvas.drawArc(rect1, 0, 360, true, paint);
if (coreBitmap != null) {
canvas.drawBitmap(coreBitmap, coreX - coreBitmap.getWidth() / 2, coreY - coreBitmap.getHeight() / 2, null);
}
}
}
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchTime = new Date().getTime();
float textX = event.getX();
float textY = event.getY();
int distanceLine = (int) getDisForTwoSpot(coreX, coreY, textX, textY);
if (distanceLine <= roundRadius) {
onClickState = -1;
} else if (distanceLine <= getWidth() / 2) {
float sweepAngle = 360 / roundMenus.size();
int angle = getRotationBetweenLines(coreX, coreY, textX, textY);
angle = (angle + 360 - 90 - (int) deviationDegree) % 360;
onClickState = (int) (angle / sweepAngle);
} else {
onClickState = -2;
}
invalidate();
break;
case MotionEvent.ACTION_UP:
if ((new Date().getTime() - touchTime) < 300) {
OnClickListener onClickListener = null;
if (onClickState == -1) {
onClickListener = onCoreClickListener;
} else if (onClickState >= 0 && onClickState < roundMenus.size()) {
onClickListener = roundMenus.get(onClickState).onClickListener;
}
if (onClickListener != null) {
onClickListener.onClick(this);
}
}
onClickState = -2;
invalidate();
break;
}
return true;
}
public void addRoundMenu(RoundMenu roundMenu) {
if (roundMenu == null) {
return;
}
if (roundMenus == null) {
roundMenus = new ArrayList<>();
}
roundMenus.add(roundMenu);
invalidate();
}
public void setCoreMenu(int coreMenuColor, int coreMenuSelectColor, int coreMenuStrokeColor, int coreMenuStrokeSize, double radiusDistance,Bitmap bitmap, OnClickListener onClickListener) {
isCoreMenu = true;
this.coreMenuColor = coreMenuColor;
this.radiusDistance = radiusDistance;
this.coreMenuSelectColor = coreMenuSelectColor;
this.coreMenuStrokeColor = coreMenuStrokeColor;
this.coreMenuStrokeSize = coreMenuStrokeSize;
coreBitmap = bitmap;
this.onCoreClickListener = onClickListener;
invalidate();
}
public static int getRotationBetweenLines(float centerX, float centerY, float xInView, float yInView) {
double rotation = 0;
double k1 = (double) (centerY - centerY) / (centerX * 2 - centerX);
double k2 = (double) (yInView - centerY) / (xInView - centerX);
double tmpDegree = Math.atan((Math.abs(k1 - k2)) / (1 + k1 * k2)) / Math.PI * 180;
if (xInView > centerX && yInView < centerY) {
rotation = 90 - tmpDegree;
} else if (xInView > centerX && yInView > centerY)
{
rotation = 90 + tmpDegree;
} else if (xInView < centerX && yInView > centerY) {
rotation = 270 - tmpDegree;
} else if (xInView < centerX && yInView < centerY) {
rotation = 270 + tmpDegree;
} else if (xInView == centerX && yInView < centerY) {
rotation = 0;
} else if (xInView == centerX && yInView > centerY) {
rotation = 180;
}
return (int) rotation;
}
public static double getDisForTwoSpot(float x1, float y1, float x2, float y2) {
float width, height;
if (x1 > x2) {
width = x1 - x2;
} else {
width = x2 - x1;
}
if (y1 > y2) {
height = y2 - y1;
} else {
height = y2 - y1;
}
return Math.sqrt((width * width) + (height * height));
}
public static class RoundMenu {
public boolean useCenter = true;
public int solidColor = 0x00000000;
public int selectSolidColor = 0x00000000;
public int strokeColor = 0x00000000;
public int strokeSize = 1;
public Bitmap icon;
public OnClickListener onClickListener;
public double iconDistance = 0.63;
}
}
然后是调用,调用代码就简单的放几句吧,应该看得懂的
RoundMenuView.RoundMenu roundMenu = new RoundMenuView.RoundMenu();
roundMenu.selectSolidColor = ColorUtils.getColor(getActivity(), R.color.gray_9999);
roundMenu.strokeColor = ColorUtils.getColor(getActivity(), R.color.gray_9999);
roundMenu.icon=ImageUtils.drawable2Bitmap(getActivity(),R.drawable.ic_right);
roundMenu.onClickListener=new OnClickListener() {
@Override
public void onClick(View view) {
ToastUtils.showToast(getActivity(),"点击了1");
}
};
roundMenuView.addRoundMenu(roundMenu);
roundMenu = new RoundMenuView.RoundMenu();
roundMenu.selectSolidColor = ColorUtils.getColor(getActivity(), R.color.gray_9999);
roundMenu.strokeColor = ColorUtils.getColor(getActivity(), R.color.gray_9999);
roundMenu.icon=ImageUtils.drawable2Bitmap(getActivity(),R.drawable.ic_right);
roundMenu.onClickListener=new OnClickListener() {
@Override
public void onClick(View view) {
ToastUtils.showToast(getActivity(),"点击了2");
}
};
roundMenuView.addRoundMenu(roundMenu);
roundMenu = new RoundMenuView.RoundMenu();
roundMenu.selectSolidColor = ColorUtils.getColor(getActivity(), R.color.gray_9999);
roundMenu.strokeColor = ColorUtils.getColor(getActivity(), R.color.gray_9999);
roundMenu.icon=ImageUtils.drawable2Bitmap(getActivity(),R.drawable.ic_right);
roundMenu.onClickListener=new OnClickListener() {
@Override
public void onClick(View view) {
ToastUtils.showToast(getActivity(),"点击了3");
}
};
roundMenuView.addRoundMenu(roundMenu);
roundMenu = new RoundMenuView.RoundMenu();
roundMenu.selectSolidColor = ColorUtils.getColor(getActivity(), R.color.gray_9999);
roundMenu.strokeColor = ColorUtils.getColor(getActivity(), R.color.gray_9999);
roundMenu.icon=ImageUtils.drawable2Bitmap(getActivity(),R.drawable.ic_right);
roundMenu.onClickListener=new OnClickListener() {
@Override
public void onClick(View view) {
ToastUtils.showToast(getActivity(),"点击了4");
}
};
roundMenuView.addRoundMenu(roundMenu);
roundMenuView.setCoreMenu(ColorUtils.getColor(getActivity(), R.color.gray_f2f2),
ColorUtils.getColor(getActivity(), R.color.gray_9999), ColorUtils.getColor(getActivity(), R.color.gray_9999)
, 1, 0.43,ImageUtils.drawable2Bitmap(getActivity(),R.drawable.ic_ok), new OnClickListener() {
@Override
public void onClick(View view) {
ToastUtils.showToast(getActivity(),"点击了中心圆圈");
}
});
http://doutugongchang.com