自定义一个简单的圆形菜单
程序员文章站
2022-06-30 18:19:10
...
我们先看下效果图
按下去的时候会改变状态。
具体的代码。
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.qiang.circlemenu.R;
/**
* Created by qiang on 2017/9/14 0014.
*/
public class CircleMenuView extends View {
private int[] array = {getResources().getColor(R.color.c1), getResources().getColor(R.color.c2), getResources().getColor(R.color.c3), getResources().getColor(R.color.c4)};
private int color = getResources().getColor(R.color.back);
private Paint rPaint;//文字
private Paint mPaint;//大圆
private Paint mPaint2;//小圆
private Paint paint3;
private Rect rT,rL,rR,rB,rC,circle;
private Rect mBound;//处理文字居中用的
private int count = -1;//点击的是那个
public CircleMenuView(Context context) {
this(context, null);
}
public CircleMenuView(Context context, AttributeSet attrs) {
this(context, attrs, -1);
}
public CircleMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setColor(color);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(1);
mPaint.setStyle(Paint.Style.STROKE);
mPaint2 = new Paint();
mPaint2.setColor(getResources().getColor(R.color.cl1));
mPaint2.setAntiAlias(true);
mPaint2.setStrokeWidth(2);
mPaint2.setStyle(Paint.Style.FILL);
paint3 = new Paint();
rPaint = new Paint();
rPaint.setColor(color);
rPaint.setTextSize(18);
rT = new Rect();
rB = new Rect();
rL = new Rect();
rR = new Rect();
rC = new Rect();
circle = new Rect();
mBound = new Rect();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(300, 300);//这里我把控件的高度写死了
}
@Override
protected void onDraw(Canvas canvas) {
setFX(canvas);
mDrawCirle(canvas);
}
private void setFX(Canvas canvas) {//4个方向的值
int l, t, r, b;
int jd = 45;
RectF rectF = new RectF(0, 0, 300, 300);// l t r b
for (int i = 0; i < 4; i++) {
if (count==i) {//如果按压了,改变颜色
paint3.setColor(Color.RED);
} else {//否则用默认的
paint3.setColor(array[i]);
}
canvas.drawArc(rectF, jd, 90, true, paint3);//4个圆弧的位置
jd += 90;
}
setTText(canvas, 150, 65, "上");
setTText(canvas, 235, 150, "右");
setTText(canvas, 150, 235, "下");
setTText(canvas, 65, 150, "左");
}
private void setTText(Canvas canvas, int startx, int starty, String str) {
rPaint.getTextBounds(str, 0, str.length(), mBound);
float textWidth = rPaint.measureText(str);//文字自己的宽度
float startX = startx - textWidth / 2;//宽度居中 mwidth的一半 - 自己的宽度
Paint.FontMetricsInt fm = rPaint.getFontMetricsInt();
int startY = starty - fm.descent + (fm.bottom - fm.top) / 2;//高度居中 这个公式是网上找的 高度差不多也在这样的算法
canvas.drawText(str, startX, startY, rPaint);
}
private void mDrawCirle(Canvas canvas) {
canvas.drawCircle(150, 150, 150, mPaint);//大圆
canvas.drawCircle(150, 150, 40, mPaint2);//小圆
mDrawTexts(canvas, rPaint);//ok字
}
private void mDrawTexts(Canvas canvas, Paint p) {//居中
p.getTextBounds("ok", 0, 1, mBound);
float textWidth = p.measureText("ok");//文字自己的宽度
float startX = 300 / 2 - textWidth / 2;//宽度居中 mwidth的一半 - 自己的宽度
Paint.FontMetricsInt fm = p.getFontMetricsInt();
int startY = 300 / 2 - fm.descent + (fm.bottom - fm.top) / 2;//高度居中 这个公式是网上找的 高度差不多也在这样的算法
canvas.drawText("ok", startX, startY, p);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float x = event.getX();
float y = event.getY();
if (x>=110&&x<=190&&y>25&&y<105) {//上的按压事件
count=2;
invalidate();//重绘
}
if (x>195&&x<275&&y>110&&y<190){//右
count=3;
invalidate();
}
if (x>110&&x<190&&y>195&&y<275){//下
count=0;
invalidate();
}
if (x>25&&x<105&&y>110&&y<190){//左
count=1;
invalidate();
}
break;
case MotionEvent.ACTION_UP://松开取消
count=-1;
invalidate();
break;
}
return true;
}
}
上一篇: 简易菜单界面