简单的自定义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();
    }

}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值