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

简单的自定义View TimePanel

程序员文章站 2022-05-30 20:26:58
...

先上图

简单的自定义View TimePanel

没错,就是Android 群英传上面的例子。

实现思路:按照现实绘画步骤:先画圆圈 然后竖线 文字最后画指针

要点:cavas.rotate() 画布旋转 也就是坐标系的旋转

cavas.translate() 坐标系的平移

public class TimePanel extends View {
    private int mWidth;
    private int mHeight;
    private boolean inited = false;
    private Paint mPaint;
    private static final int maxLineSize = 24;
    private int mHourLength = 50;
    private int mMinuteLength = 30;

    private int second = 0;
    private int minutes = 0;
    private int hour = 0;

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

    public TimePanel(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public TimePanel(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

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

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (!inited) {
            inited = true;
            mWidth = getMeasuredWidth();
            mHeight = getMeasuredHeight();
            init();
        }
    }

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


    @Override
    protected void onDraw(Canvas canvas) {
        //1.绘制外层圆环
        drawOutCircle(canvas);
        //2.绘制刻度
        drawInnerLine(canvas);
        //3.绘制指针
        drawSecondMinutes(canvas);
        //保存当前绘制
        canvas.save();
        //绘制之后的合并
        canvas.restore();
        super.onDraw(canvas);
    }


    private void drawOutCircle(Canvas canvas) {
        //空心
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(5);
        mPaint.setColor(Color.BLACK);
        canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mPaint);
    }

    private void drawInnerLine(Canvas canvas) {
        for (int i = 0; i < maxLineSize; i++) {
            if (i == 0 || i == 6 || i == 12 || i == 18) {
                drawHour(canvas);
            } else {
                drawMinutes(canvas);
            }
            drawText(canvas, String.valueOf(i));
            //旋转默认是以左上角为圆心
            canvas.rotate(15, mWidth / 2, mHeight / 2);
        }
    }

    private void drawHour(Canvas canvas) {
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(5);
        mPaint.setColor(Color.BLACK);
        canvas.drawLine(mWidth / 2, (mHeight / 2 - mWidth / 2), mWidth / 2, (mHeight / 2 - mWidth / 2) + mHourLength, mPaint);
    }


    private void drawMinutes(Canvas canvas) {
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(3);
        mPaint.setColor(Color.GRAY);
        canvas.drawLine(mWidth / 2, (mHeight / 2 - mWidth / 2), mWidth / 2, (mHeight / 2 - mWidth / 2) + mMinuteLength, mPaint);
    }

    private void drawText(Canvas canvas, String text) {
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setTextSize(30);
        //获取文字的宽度
        float textWidth = mPaint.measureText(text);
        canvas.drawText(text, (mWidth - textWidth) / 2, (mHeight / 2 - mWidth / 2) + mHourLength + 15 + 10, mPaint);
    }


    private void drawHourPointer(Canvas canvas) {

    }

    private void drawMinutesPointer(Canvas canvas) {

    }

    private void drawSecondMinutes(Canvas canvas) {
        //旋转角度
        canvas.rotate(second * 15, mWidth / 2, mHeight / 2);
        canvas.translate(mWidth / 2, mHeight / 2);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(10);
        canvas.drawLine(0, 0, 0, -mWidth/4, mPaint);
    }

    //更新秒
    public void updateSecond(int second) {
        this.second = second;
        invalidate();
    }

}

刚做得时候觉得可能无从下手,但是看了两眼书上写的,就知道怎么做了,主要还是几个方法不太了解,平时用的太少了!