这里延用之前的模板,主要是在FrontFragment页面添加一个自定义的温度仪表盘用于显示温度。

先看效果图(原谅这尴尬的配色,这就是一个小demo):

第一步:首先创建一个自定义View(TempDashboardView.java)

 在TempDashboardView里先继承View类, 然后进行下面的操作:

第二步:获取画布中心值

在onMeasure中利用getMeasureWidth()和getMeasureHeight()来获取画布的中心值(注意:这里的中心值并不是屏幕的中心值而是画布的),在我这个项目中我把中心值的Y轴向下移了,没什么特别的意思,就是在我其它项目这个位置好看,但是在这里我懒得改。

centerX = getMeasuredWidth() / 2;
centerY = getMeasuredHeight() / 2 + 100;

第三步:初始化画笔(这个初始化函数得在默认添加的View方法中)

 

    private void init() {

//      定义圆画笔
        cPaint = new Paint();
        cPaint.setAntiAlias(true);
        cPaint.setAntiAlias(true);
        cPaint.setStyle(Paint.Style.STROKE);
        cPaint.setColor(0xFF0698DA);
        cPaint.setStrokeCap(Paint.Cap.ROUND);
        cPaint.setStrokeWidth(5);

//      定义刻度画笔
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(0xFF0698DA);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(POINT_STROKE_WIDTH);

//      定义文字画笔
        tPaint = new Paint();
        tPaint.setAntiAlias(true);
        tPaint.setStyle(Paint.Style.FILL);
        tPaint.setColor(Color.BLUE);
        tPaint.setStrokeCap(Paint.Cap.ROUND);
        tPaint.setStrokeWidth(TITLE_STROKE_WIDTH);
        tPaint.setTextAlign(Paint.Align.CENTER);

//      定义指针画笔
        pPaint = new Paint();
        pPaint.setAntiAlias(true);
        pPaint.setStyle(Paint.Style.FILL);
        pPaint.setColor(Color.BLUE);

//      定义内圆画笔
        iPaint = new Paint();
        iPaint.setAntiAlias(true);
        iPaint.setColor(0xFF03DAC5);
    }

第四步:绘制圆盘的圆(圆盘由两个同心圆构成)

    private void onDrawCircle(Canvas canvas) {

//      表盘内圆
        inRectF = new RectF(centerX - CIRCLE_RADIUS_IN, centerY - CIRCLE_RADIUS_IN, centerX + CIRCLE_RADIUS_IN, centerY + CIRCLE_RADIUS_IN);
        canvas.drawArc(inRectF, STAT_ANGLE, SWEEP_ANGLE, false, cPaint);

//      表盘外圆
        outRectF = new RectF(centerX - CIRCLE_RADIUS_OUT, centerY - CIRCLE_RADIUS_OUT, centerX + CIRCLE_RADIUS_OUT, centerY + CIRCLE_RADIUS_OUT);
        canvas.drawArc(outRectF, STAT_ANGLE, SWEEP_ANGLE, false, cPaint);

    }

第五步:绘制刻度线

    private void onDrawLine(Canvas canvas) {
        canvas.save();

        startX = centerX - CIRCLE_RADIUS_OUT;
        startY = centerY;
        stopX = centerX - 330;
        stopY = centerY;

        canvas.rotate(-STAT_ANGLE, centerX, centerY);

        for (int i = 0; i <= 70; i ++) {
            if (i % 10 == 0) {
                canvas.drawLine(startX, startY, stopX + LONG_POINT, stopY, mPaint);
            }
            else if (i % 5 == 0)
                canvas.drawLine(startX, startY, stopX + SHORT_POINT, stopY, mPaint);
            else
                canvas.drawLine(startX, startY, stopX, stopY, mPaint);

            canvas.rotate(ROTATION_ANGLE, centerX, centerY);
        }

        canvas.restore();

    }

第六步:绘制文本(包括圆盘外面的文本和圆盘内的文本)

    private void onDrawText(Canvas canvas) {

        tPaint.setTextSize(45);
        canvas.drawCircle(centerX, centerY, 120, iPaint);
        canvas.drawText("35.0°C", centerX, centerY, tPaint);

//      刻度文字绘制
        tPaint.setStrokeWidth(TITLE_STROKE_WIDTH);
        tPaint.setTextSize(POINT_TEXT_SIZE);

        int num = 0;
        for (int i = -200; i <= 15; i ++) {

            double distanceX = (CIRCLE_RADIUS_OUT + 30) * Math.cos(i * Math.PI / 180);
            double distanceY = (CIRCLE_RADIUS_OUT + 30) * Math.sin(i * Math.PI / 180);

            if (i % 15 == 0) {
                currentX = (float) (centerX + distanceX);
                currentY = (float) (centerY + distanceY);
                canvas.drawText(String.valueOf(-20 + num * 5), currentX, currentY, tPaint);
                num ++;
            }
        }

        tPaint.setTextSize(TITLE_TEXT_SIZE);
        canvas.drawText(string, centerX, centerY + 100, tPaint);

    }

第七步:绘制指针

    private void onDrawPoint(Canvas canvas) {

        canvas.save();

        Path path = new Path();

        canvas.rotate(60, centerX, centerY);

        path.moveTo(centerX, centerY - 300);
        path.lineTo(centerX - 10, centerY);
        path.lineTo(centerX + 10, centerY);
        path.lineTo(centerX, centerY - 300);
        path.close();

        canvas.drawPath(path, pPaint);

        canvas.restore();
    }

第八步:重绘onDraw()方法

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

//      画圆盘
        onDrawCircle(canvas);
//      画刻度
        onDrawLine(canvas);
//      画指针
        onDrawPoint(canvas);
//      画文字
        onDrawText(canvas);
    }

第九步:常数的定义

    private static final int ROTATION_ANGLE = 3;       // 旋转角度
    private static final int LONG_POINT = 40;          // 长刻度线
    private static final int SHORT_POINT = 20;         // 短刻度线
    private static final int TITLE_TEXT_SIZE = 60;     // 标题文字大小
    private static final int POINT_TEXT_SIZE = 30;     // 刻度文字大小
    private static final int TITLE_STROKE_WIDTH = 1;   // 标题画笔宽度
    private static final int POINT_STROKE_WIDTH = 5;   // 刻度画笔宽度
    private static final int CIRCLE_RADIUS_IN = 200;   // 内圆半径
    private static final int CIRCLE_RADIUS_OUT = 350;  // 外圆半径
    private static final int STAT_ANGLE = 15;          // 开始角度
    private static final int SWEEP_ANGLE = -210;       // 扫过角度

更多推荐