美文网首页
Android 的一个简单的遥控器自定义控件

Android 的一个简单的遥控器自定义控件

作者: 远行的猿 | 来源:发表于2017-01-24 11:30 被阅读0次

做一个智能风扇时 客户有一个智能遥控器的需求,就写了个比较简单的自定义控件。代码注释很详细了,就不多说了。自己看下啦,有问题的问题一起交流下。

效果如下图:

遥控器截图.png
/**
 * Created by zxd on 2016/6/27.
 */
public class DiskMenuViewEight extends View {

    //内圆边框的宽度
    private float innerCircleWidth = 10;

    //外围圆的边框的宽度
    private float outerCircleWidth = 15;

    //画笔对象
    private Paint mPaint;

    //圆心的X坐标
    private float centerX;

    //圆心的Y坐标
    private float centerY;

    //内圆半径的颜色
    private int outerCircleColor = 0xFFD8D9D9;

    //外围半径的颜色 、点击的颜色
    private int innerCircleColor = 0xFFF1F1F1;

    //37°正弦值
    private float mSin45 = (float) Math.sin(45 * Math.PI / 180);

    //37°的余弦值

    private float mCos45 = (float) Math.cos(45 * Math.PI / 180);


    private float outerCircleRadius, innerCircleRadius;


    private AREA mArea;

    public DiskMenuViewEight(Context context) {
        super(context);
        init();
    }

    //长度
    int mWidth;
    //高度
    int mHeight;

    public void setWidthAndHeight(int w, int h) {
        this.mWidth = w;
        this.mHeight = h;

    }

    public DiskMenuViewEight(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

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

        int w = mWidth;
        int h = mHeight;

        centerX = w / 2;

        centerY = h / 2;

        outerCircleRadius = centerX - outerCircleWidth;

        innerCircleRadius = centerX / 3;

    }

    private void init() {
        mPaint = new Paint();
    }

    //定义接口
    public interface ChangeStateListener {
        void onChangeState(AREA area);
    }

    ChangeStateListener mChangeStateListener = null;

    public void setChangeStateListener(ChangeStateListener changeStateListener) {
        mChangeStateListener = changeStateListener;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mPaint.setAntiAlias(true);
        //画圆
        drawCircle(canvas);
        //花直线
        drawLine(canvas);
        //画背景选择器
        drawOnclikColor(canvas, mArea);
        //画文字
        drawText(canvas);
        //画图
        drawImageView1(canvas);
        drawImageView2(canvas);
        //画灯泡
        drawImageViewCenter(canvas);
    }


    //画图
    private void drawImageView1(Canvas canvas) {
        Paint imgPaint = new Paint();
        imgPaint.setAntiAlias(true);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.reversal);

        Matrix matrix = new Matrix();
        matrix.postScale(0.3f, 0.3f);
        Bitmap dstbmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                bitmap.getHeight(), matrix, true);

        RectF mRectF = new RectF((float) (centerX - (mSin45 * outerCircleRadius) / 3 - UiUtil.Dp2Px(20)), (float) (centerY + (0.55f * outerCircleRadius) - UiUtil.Dp2Px(10)),
                (float) ((centerX - (mSin45 * outerCircleRadius) / 3) + UiUtil.Dp2Px(20)), (float) (centerY + (0.55f * outerCircleRadius) + UiUtil.Dp2Px(30)));
        canvas.drawBitmap(dstbmp, null, mRectF, imgPaint);
    }

    //画图
    private void drawImageView2(Canvas canvas) {
        Paint imgPaint = new Paint();
        imgPaint.setAntiAlias(true);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.wind_speed);

        Matrix matrix = new Matrix();
        matrix.postScale(0.3f, 0.3f);
        Bitmap dstbmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                bitmap.getHeight(), matrix, true);

        RectF mRectF = new RectF((float) (centerX + (mSin45 * outerCircleRadius) / 3 - UiUtil.Dp2Px(20)), (float) (centerY + (0.55f * outerCircleRadius) - UiUtil.Dp2Px(10)),
                (float) ((centerX + (mSin45 * outerCircleRadius) / 3) + UiUtil.Dp2Px(20)), (float) (centerY + (0.55f * outerCircleRadius) + UiUtil.Dp2Px(30)));
        canvas.drawBitmap(dstbmp, null, mRectF, imgPaint);
    }

    //画图
    private void drawImageViewCenter(Canvas canvas) {
        Paint imgPaint = new Paint();
        imgPaint.setAntiAlias(true);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.off_light);

        Matrix matrix = new Matrix();
        matrix.postScale(0.4f, 0.4f);
        Bitmap dstbmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                bitmap.getHeight(), matrix, true);

        RectF mRectF = new RectF((float) (centerX - UiUtil.Dp2Px(30)), (float) (centerY - UiUtil.Dp2Px(30)),
                (float) (centerX + UiUtil.Dp2Px(30)), (float) (centerY + UiUtil.Dp2Px(30)));
        canvas.drawBitmap(dstbmp, null, mRectF, imgPaint);
    }

    //写文字
    private void drawText(Canvas canvas) {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextSize(100);
        paint.setColor(innerCircleColor);
        paint.setTextAlign(Paint.Align.CENTER);


        //写1
        canvas.drawText("1", centerX - mSin45 * (outerCircleRadius / 2) - (outerCircleRadius - innerCircleRadius) * 2 / 5,
                centerY + mSin45 * (outerCircleRadius / 2) - (outerCircleRadius - innerCircleRadius) / 20, paint);

        //写2
        canvas.drawText("2", centerX - mSin45 * (outerCircleRadius / 2) - (outerCircleRadius - innerCircleRadius) * 2 / 5,
                centerY - mCos45 * (outerCircleRadius / 4), paint);
        //写3
        canvas.drawText("3", centerX - (mSin45 * outerCircleRadius) / 3, centerY - (0.55f * outerCircleRadius), paint);

        //写4
        canvas.drawText("4", centerX + mSin45 * (outerCircleRadius / 3),
                centerY - (0.55f * outerCircleRadius), paint);
        //写5
        canvas.drawText("5", centerX + mSin45 * (outerCircleRadius / 2) + (outerCircleRadius - innerCircleRadius) * 2 / 5,
                centerY - mCos45 * (outerCircleRadius / 4), paint);
        //写6
        canvas.drawText("6", centerX + mSin45 * (outerCircleRadius / 2) + (outerCircleRadius - innerCircleRadius) * 2 / 5,
                centerY + mSin45 * (outerCircleRadius / 2) - (outerCircleRadius - innerCircleRadius) / 20, paint);

    }

    //画圆
    private void drawCircle(Canvas canvas) {
        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(centerX, centerY, outerCircleRadius, mPaint);

        mPaint.setColor(outerCircleColor);
        mPaint.setStrokeWidth(outerCircleWidth);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(centerX, centerY, outerCircleRadius, mPaint);

        mPaint.setColor(outerCircleColor);
        mPaint.setStrokeWidth(10);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(centerX, centerY, innerCircleRadius, mPaint);

        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(centerX, centerY, innerCircleRadius, mPaint);


    }

    //画直线
    private void drawLine(Canvas canvas) {
        mPaint.setColor(outerCircleColor);
        mPaint.setStrokeWidth(5);
        //第一条
        canvas.drawLine(centerX, centerY - innerCircleRadius, centerX, centerY - outerCircleRadius, mPaint);
        //第二条
        canvas.drawLine(centerX - (mSin45 * outerCircleRadius), centerY - (mSin45 * outerCircleRadius),
                centerX - (mSin45 * innerCircleRadius), centerY - (mSin45 * innerCircleRadius), mPaint);
        //第三条
        canvas.drawLine(centerX - innerCircleRadius, centerY, centerX - outerCircleRadius, centerY, mPaint);
        //第四条
        canvas.drawLine(centerX - (mSin45 * outerCircleRadius), centerY + (mSin45 * outerCircleRadius),
                centerX - (mSin45 * innerCircleRadius), centerY + (mSin45 * innerCircleRadius), mPaint);
        //第五条
        canvas.drawLine(centerX - (mSin45 * outerCircleRadius), centerY + (mSin45 * outerCircleRadius),
                centerX - (mSin45 * innerCircleRadius), centerY + (mSin45 * innerCircleRadius), mPaint);
        //第六条
        canvas.drawLine(centerX, centerY + innerCircleRadius, centerX, centerY + outerCircleRadius, mPaint);
        //第七条
        canvas.drawLine(centerX + (mSin45 * outerCircleRadius), centerY + (mSin45 * outerCircleRadius),
                centerX + (mSin45 * innerCircleRadius), centerY + (mSin45 * innerCircleRadius), mPaint);
        //第八条
        canvas.drawLine(centerX + innerCircleRadius, centerY, centerX + outerCircleRadius, centerY, mPaint);
        //第九条
        canvas.drawLine(centerX + (mSin45 * outerCircleRadius), centerY - (mSin45 * outerCircleRadius),
                centerX + (mSin45 * innerCircleRadius), centerY - (mSin45 * innerCircleRadius), mPaint);
    }


    /**
     * 清空画布
     *
     * @param canvas
     */
    private void clearCanvas(Canvas canvas) {
        canvas.drawColor(Color.WHITE);
    }

    //按下时的X,Y坐标
    float mDownX, mDownY;
    //松开时的X,Y坐标
    float mUpX, mUpY;

    //触摸事件 即点击事件的处理


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownX = event.getX();
                mDownY = event.getY();
                Log.i("custom", "mDown==" + mDownX);
                Log.i("custom", "mDown==" + judgeArea(mDownX, mDownY));
                mArea = judgeArea(mDownX, mDownY);
                invalidate();
                mChangeStateListener.onChangeState(mArea);
                break;
            case MotionEvent.ACTION_UP:
//                clearCanvas(mCanvas);
                mArea = null;
                invalidate();
                break;
            default:
                break;
        }

        return true;
    }


    //判断区域
    public AREA judgeArea(float x, float y) {
        //判断是是否在大圆内
        if ((x - centerX) * (x - centerX) + (y - centerY) * (y - centerY) <= outerCircleRadius * outerCircleRadius) {
            //判断是否在小圆内
            if ((x - centerX) * (x - centerX) + (y - centerY) * (y - centerY) > innerCircleRadius * innerCircleRadius) {
                x = x - centerX;
                y = y - centerY;
                float tan = y / x;
                if (tan > Math.tan(45 * Math.PI / 180) && tan < Integer.MAX_VALUE && x < 0 && y < 0) {
                    return AREA.NUMBER_ONE;
                } else if (tan > 0 && tan < Math.tan(45 * Math.PI / 180) && x < 0 && y < 0) {
                    return AREA.NUMBER_TWO;
                } else if (tan < 0 && tan > -Math.tan(45 * Math.PI / 180) && x < 0 && y > 0) {
                    return AREA.NUMBER_THREE;
                } else if (tan < -Math.tan(45 * Math.PI / 180) && tan > Integer.MIN_VALUE && x < 0 && y > 0) {
                    return AREA.NUMBER_FOUR;
                } else if (tan > Math.tan(45 * Math.PI / 180) && tan < Integer.MAX_VALUE && x > 0 && y > 0) {
                    return AREA.NUMBER_FIVE;
                } else if (tan > 0 && tan < Math.tan(45 * Math.PI / 180) && x > 0 && y > 0) {
                    return AREA.NUMBER_SIX;
                } else if (tan > -Math.tan(45 * Math.PI / 180) && tan < 0 && x > 0 && y < 0) {
                    return AREA.NUMBER_SEVEN;
                } else if (tan > Integer.MIN_VALUE && tan < -Math.tan(45 * Math.PI / 180) && x > 0 && y < 0) {
                    return AREA.NUMBER_EIGHT;
                }
            } else {
                return AREA.CENTER;
            }
        } else {
            return null;
        }
        return null;
    }


    /**
     * 点击的时候绘制深色的扇形
     *
     * @param canvas
     * @param area
     */
    private void drawOnclikColor(Canvas canvas, AREA area) {
        //先诀条件
        if (area == null) {
            return;
        }
        //设置点击之后的颜色
        mPaint.setColor(outerCircleColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(outerCircleRadius - innerCircleRadius);

        switch (area) {
            case NUMBER_ONE:
                canvas.drawArc(new RectF(centerX - (outerCircleRadius - innerCircleRadius) - innerCircleWidth, centerY - (outerCircleRadius - innerCircleRadius) - innerCircleWidth,
                        centerX + (outerCircleRadius - innerCircleRadius) + innerCircleWidth, centerY
                        + (outerCircleRadius - innerCircleRadius) + innerCircleWidth), 225, 45, false, mPaint);
                break;
            case NUMBER_TWO:
                canvas.drawArc(new RectF(centerX - (outerCircleRadius - innerCircleRadius) - innerCircleWidth, centerY - (outerCircleRadius - innerCircleRadius) - innerCircleWidth,
                        centerX + (outerCircleRadius - innerCircleRadius) + innerCircleWidth, centerY
                        + (outerCircleRadius - innerCircleRadius) + innerCircleWidth), 180, 45, false, mPaint);
                break;
            case NUMBER_THREE:
                canvas.drawArc(new RectF(centerX - (outerCircleRadius - innerCircleRadius) - innerCircleWidth, centerY - (outerCircleRadius - innerCircleRadius) - innerCircleWidth,
                        centerX + (outerCircleRadius - innerCircleRadius) + innerCircleWidth, centerY
                        + (outerCircleRadius - innerCircleRadius) + innerCircleWidth), 135, 45, false, mPaint);
                break;
            case NUMBER_FOUR:
                canvas.drawArc(new RectF(centerX - (outerCircleRadius - innerCircleRadius) - innerCircleWidth, centerY - (outerCircleRadius - innerCircleRadius) - innerCircleWidth,
                        centerX + (outerCircleRadius - innerCircleRadius) + innerCircleWidth, centerY
                        + (outerCircleRadius - innerCircleRadius) + innerCircleWidth), 90, 45, false, mPaint);
                break;
            case NUMBER_FIVE:
                canvas.drawArc(new RectF(centerX - (outerCircleRadius - innerCircleRadius) - innerCircleWidth, centerY - (outerCircleRadius - innerCircleRadius) - innerCircleWidth,
                        centerX + (outerCircleRadius - innerCircleRadius) + innerCircleWidth, centerY
                        + (outerCircleRadius - innerCircleRadius) + innerCircleWidth), 45, 45, false, mPaint);
                break;
            case NUMBER_SIX:
                canvas.drawArc(new RectF(centerX - (outerCircleRadius - innerCircleRadius) - innerCircleWidth, centerY - (outerCircleRadius - innerCircleRadius) - innerCircleWidth,
                        centerX + (outerCircleRadius - innerCircleRadius) + innerCircleWidth, centerY
                        + (outerCircleRadius - innerCircleRadius) + innerCircleWidth), 0, 45, false, mPaint);
                break;
            case NUMBER_SEVEN:
                canvas.drawArc(new RectF(centerX - (outerCircleRadius - innerCircleRadius) - innerCircleWidth, centerY - (outerCircleRadius - innerCircleRadius) - innerCircleWidth,
                        centerX + (outerCircleRadius - innerCircleRadius) + innerCircleWidth, centerY
                        + (outerCircleRadius - innerCircleRadius) + innerCircleWidth), -45, 45, false, mPaint);
                break;
            case NUMBER_EIGHT:
                canvas.drawArc(new RectF(centerX - (outerCircleRadius - innerCircleRadius) - innerCircleWidth, centerY - (outerCircleRadius - innerCircleRadius) - innerCircleWidth,
                        centerX + (outerCircleRadius - innerCircleRadius) + innerCircleWidth, centerY
                        + (outerCircleRadius - innerCircleRadius) + innerCircleWidth), -90, 45, false, mPaint);
                break;
            case CENTER:
                mPaint.setStrokeWidth(0);
                mPaint.setStyle(Paint.Style.FILL);
                canvas.drawCircle(centerX, centerY, innerCircleRadius, mPaint);
                break;
            default:
                break;
        }

    }

    /**
     * 关于不同区域的枚举,逆时针方向
     */
    public enum AREA {
        //第一区域
        NUMBER_ONE,
        //第二区域
        NUMBER_TWO,
        //第三区域
        NUMBER_THREE,
        //第四区域
        NUMBER_FOUR,
        //第五区域
        NUMBER_FIVE,
        //第六区域
        NUMBER_SIX,
        //第七区域
        NUMBER_SEVEN,
        //第八区域
        NUMBER_EIGHT,
        //中心区域
        CENTER,
    }
}

相关文章

网友评论

      本文标题:Android 的一个简单的遥控器自定义控件

      本文链接:https://www.haomeiwen.com/subject/tyezbttx.html