欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自定义一个简单的圆形菜单

程序员文章站 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;
    }
}



相关标签: 圆形菜单