自定义View圆盘遥控器

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.ysten.videoplus.client.R;
import com.ysten.videoplus.client.message.MessageEvent;

import org.greenrobot.eventbus.EventBus;

public class CircleView extends View {

    private int circleWidth = 214;//圆环直径
    private int circleColor = getResources().getColor(R.color.color_1F1F1F);
    private int innerCircleColor = getResources().getColor(R.color.color_1F1F1F);
    private int backgroundColor = getResources().getColor(R.color.color_151515);

    private Paint paint = new Paint();
    int center = 0;
    int innerRadius = 0;
    private float innerCircleRadius = 0;
    //    private float smallCircle = 10;
    public Dir dir = Dir.UNDEFINE;

    public CircleView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
    }

    public CircleView(Context context) {
        super(context);
    }

    public CircleView(Context context, AttributeSet attributeSet, int defStyle) {
        super(context, attributeSet, defStyle);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int measuredHeight = measureHeight(heightMeasureSpec);
        int measuredWidth = measureWidth(widthMeasureSpec);

        setMeasuredDimension(measuredWidth, measuredHeight);

        center = getWidth() / 2;//半径
        innerRadius = (center - circleWidth + 80);//圆环
        innerCircleRadius = center * 17 / 48;//内心圆半径
        this.setOnTouchListener(onTouchListener);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        initBackGround(canvas);
        drawDirTriangle(canvas, dir);
    }

    //绘制方向箭头
    private void drawDirTriangle(Canvas canvas, Dir dir) {
        paint.setColor(innerCircleColor);
        paint.setStrokeWidth(1);
        paint.setStyle(Paint.Style.FILL);

        switch (dir) {
            case UP:
                drawOnclikColor(canvas, Dir.UP);
                break;
            case DOWN:
                drawOnclikColor(canvas, Dir.DOWN);
                break;
            case LEFT:
                drawOnclikColor(canvas, Dir.LEFT);
                break;
            case RIGHT:
                drawOnclikColor(canvas, Dir.RIGHT);
                break;
            case CENTER:
                drawOnclikColor(canvas, Dir.CENTER);
                break;
            default:
                break;
        }

        Paint paints = new Paint();
        paints.setTextSize(50);//设置字体大小
        paints.setColor(getResources().getColor(R.color.white));
        canvas.drawText("确认", center - 50, center + 25, paints);
        paint.setColor(getResources().getColor(R.color.white));
        //上
        canvas.drawCircle(center, center - 300, 5, paint);
        //下
        canvas.drawCircle(center, center + 300, 5, paint);
        //左
        canvas.drawCircle(80, center, 5, paint);
        //右
        canvas.drawCircle(2 * center - 80, center, 5, paint);
    }

    private void drawOnclikColor(Canvas canvas, Dir dir) {
        paint.setColor(getResources().getColor(R.color.color_1A1A1A));
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(215);
        switch (dir) {
            case UP:
                canvas.drawArc(new RectF(center - innerRadius, center - innerRadius, center +
                        innerRadius, center + innerRadius), 225, 90, false, paint);
                EventBus.getDefault().post(new MessageEvent(MessageEvent.MSG_YKQ_UP));
                break;
            case DOWN:
                canvas.drawArc(new RectF(center - innerRadius, center - innerRadius, center +
                        innerRadius, center
                        + innerRadius), 45, 90, false, paint);
                EventBus.getDefault().post(new MessageEvent(MessageEvent.MSG_YKQ_DOWN));
                break;
            case LEFT:
                canvas.drawArc(new RectF(center - innerRadius, center - innerRadius, center +
                        innerRadius, center
                        + innerRadius), 135, 90, false, paint);
                EventBus.getDefault().post(new MessageEvent(MessageEvent.MSG_YKQ_LEFT));
                break;
            case RIGHT:
                canvas.drawArc(new RectF(center - innerRadius, center - innerRadius, center +
                        innerRadius, center
                        + innerRadius), -45, 90, false, paint);
                EventBus.getDefault().post(new MessageEvent(MessageEvent.MSG_YKQ_RIGHT));
                break;
            case CENTER:
                canvas.drawCircle(center, center, center / 12, paint);
                EventBus.getDefault().post(new MessageEvent(MessageEvent.MSG_YKQ_CENTER));
                invalidate();
                break;
            default:
                break;
        }

        paint.setStyle(Paint.Style.FILL);
    }

    private void initBackGround(Canvas canvas) {
        clearCanvas(canvas);
        drawBackCircle(canvas);
        drawInnerCircle(canvas);
    }

    private void drawInnerCircle(Canvas canvas) {
        paint.setColor(getResources().getColor(R.color.color_1F1F1F));
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(1);
        canvas.drawCircle(center, center, innerCircleRadius, paint);
    }

    private void drawBackCircle(Canvas canvas) {
        paint.setColor(circleColor);
        paint.setStrokeWidth(circleWidth);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(center, center, innerRadius, paint);//绘制圆圈
    }

    private void clearCanvas(Canvas canvas) {
        canvas.drawColor(backgroundColor);
    }

    //测量高度
    private int measureHeight(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        int result = 0;
        if (specMode == MeasureSpec.AT_MOST) {
            result = specSize;
        } else if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        }

        return result;
    }

    //测量宽度
    private int measureWidth(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        int result = 0;
        if (specMode == MeasureSpec.AT_MOST) {
            result = getWidth();
        } else if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        }
        return result;
    }

    OnTouchListener onTouchListener = new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Dir tmp = Dir.UNDEFINE;
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if ((tmp = checkDir(event.getX(), event.getY())) != Dir.UNDEFINE) {
                        dir = tmp;
                        invalidate();
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    dir = Dir.UNDEFINE;
                    invalidate();
                    break;
            }
            return true;
        }


        private Dir checkDir(float x, float y) {
            Dir dir = Dir.UNDEFINE;
            if (Math.sqrt(Math.pow(y - center, 2) + Math.pow(x - center, 2)) < innerCircleRadius) {
                //中心圆圈内
                dir = Dir.CENTER;
            } else if (y < x && y + x < 2 * center) {
                //向上
                dir = Dir.UP;
            } else if (y < x && y + x > 2 * center) {
                //向右
                dir = Dir.RIGHT;
            } else if (y > x && y + x < 2 * center) {
                //向左
                dir = Dir.LEFT;
            } else if (y > x && y + x > 2 * center) {
                //向下
                dir = Dir.DOWN;
            } else {
                dir = Dir.UNDEFINE;
            }
            return dir;
        }
    };


    public enum Dir {
        UP, DOWN, LEFT, RIGHT, CENTER, UNDEFINE
    }
}
 
参考别人扇形按钮,进行重新绘图行程的,代码中还有部分瑕疵。不够完善

                
实现圆形上下左右圆盘按钮可以通过自定义View来实现。 首先需要继承View,并且在onDraw()方法中绘制圆盘和箭头,具体实现步骤如下: 1. 定义圆盘的半径和圆心坐标 ``` private float mRadius; // 圆盘半径 private float mCenterX; // 圆盘圆心X坐标 private float mCenterY; // 圆盘圆心Y坐标 ``` 2. 在onMeasure()方法中获取View的宽高,并且计算圆盘半径和圆心坐标 ``` @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); // 获取宽度 int height = MeasureSpec.getSize(heightMeasureSpec); // 获取高度 int size = Math.min(width, height); // 取宽高的最小值作为View的大小 mRadius = size / 2f; // 计算圆盘半径 mCenterX = width / 2f; // 计算圆盘圆心X坐标 mCenterY = height / 2f; // 计算圆盘圆心Y坐标 setMeasuredDimension(size, size); // 设置View的大小 } ``` 3. 在onDraw()方法中绘制圆盘和箭头 ``` @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制圆盘 canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint); // 绘制箭头 canvas.drawLine(mCenterX, mCenterY - mRadius, mCenterX, mCenterY - mRadius / 2f, mPaint); // 上箭头 canvas.drawLine(mCenterX, mCenterY + mRadius, mCenterX, mCenterY + mRadius / 2f, mPaint); // 下箭头 canvas.drawLine(mCenterX - mRadius, mCenterY, mCenterX - mRadius / 2f, mCenterY, mPaint); // 左箭头 canvas.drawLine(mCenterX + mRadius, mCenterY, mCenterX + mRadius / 2f, mCenterY, mPaint); // 右箭头 } ``` 4. 在构造方法中初始化画笔 ``` public RoundButtonView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); // 抗锯齿 mPaint.setStyle(Paint.Style.STROKE); // 空心 mPaint.setStrokeWidth(5); // 线宽 mPaint.setColor(Color.BLACK); // 颜色 } ``` 最后,在布局文件中添加自定义View即可。 ``` <com.example.customview.RoundButtonView android:layout_width="match_parent" android:layout_height="match_parent"/> ``` 当然,这只是一个简单的实现,如果需要响应用户的手势操作,还需要重写onTouchEvent()方法,并且处理用户手势的事件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值