天天看點

從Android繪制View小例子中深入了解自定義View

平時開發界面時,Android系統為我們提供了各種各樣的View元件,TextView、ImageView、Button、LinearLayout、ScrollView、ListView等等,這些也基本滿足了平時的開發要求。有時候開發也會遇到比較刁鑽的需求,自定義View多多少少就會用到。

徹底搞懂自定義View并不容易,因為牽扯到尺寸計算、Location(定位)、Canvas、矩陣計算等等,内容還是挺多的。記得剛入門Android時很快搞定了一個自定義View,後面才發現這還遠遠不夠。

1,首先要配置View的尺寸和位置

1)比如實作一個正方形的View,保持高度和寬度一緻

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
           

2)配置View在父View中的位置,使用onLayout

@Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }
           

2,在繪制内容前,你要準備好畫筆

prPaint = new Paint();
        //防鋸齒
        prPaint.setAntiAlias(true);
        //防抖動
        prPaint.setDither(true);
        prPaint.setStrokeCap(Paint.Cap.ROUND);
        prPaint.setStyle(Paint.Style.STROKE);
        prPaint.setStrokeWidth(PR_STROKE_WIDTH);

        dot = new Path();
        //指定順時針方向(CW)
        dot.addCircle(0, 0, DOTTED_LINE_WIDTH / 2, Path.Direction.CW);

        dotPaint = new Paint();
        dotPaint.setAntiAlias(true);
        dotPaint.setDither(true);
        dotPaint.setStyle(Paint.Style.STROKE);
        dotPaint.setColor(Color.WHITE);

        innerCircle = new Paint();
        innerCircle.setAntiAlias(true);
        innerCircle.setDither(true);
        innerCircle.setStyle(Paint.Style.STROKE);
        innerCircle.setStrokeWidth(INNER_LINE);
        innerCircle.setColor(themeColor);

        effects_line = new DashPathEffect(new float[]{30, 10}, 1);
           

3,将内容通過畫布繪制出來

@Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        dotDrawRect.set(dotRect);
        final float centerX = dotDrawRect.centerX();
        final float centerY = dotDrawRect.centerY();
        float radius = dotDrawRect.width() / 2;

        initPathEffect();

        dotPaint.setPathEffect(effects1);
        canvas.drawCircle(centerX, centerY, radius, dotPaint);

        radius = radius - DOTTED_LINE_PADDING;
        dotPaint.setPathEffect(effects2);
        canvas.drawCircle(centerX, centerY, radius, dotPaint);

        radius = radius - DOTTED_LINE_PADDING;
        dotPaint.setPathEffect(effects3);
        canvas.drawCircle(centerX, centerY, radius, dotPaint);

        radius = radius - DOTTED_LINE_PADDING;
        dotPaint.setPathEffect(effects4);
        canvas.drawCircle(centerX, centerY, radius, dotPaint);

        radius = radius - DOTTED_LINE_PADDING;
        innerCircle.setPathEffect(null);
        innerCircle.setColor(Color.WHITE);
        canvas.drawCircle(centerX, centerY, radius, innerCircle);

        radius = (float) (radius - DOTTED_LINE_PADDING * 1.5);
        innerCircle.setPathEffect(effects_line);
        innerCircle.setColor(themeColor);
        canvas.drawCircle(centerX, centerY, radius, innerCircle);

        radius = radius - PR_STROKE_WIDTH / 2 - DOTTED_LINE_PADDING / 2;

        if (powInterRadius == 0) {
            powInterRadius = Math.pow(radius, 2);
        }
        //進度條繪制
        dotDrawRect.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
        prPaint.setColor(Color.GRAY);
        canvas.drawArc(dotDrawRect, 120, 300, false, prPaint);

        prPaint.setColor(Color.WHITE);
        canvas.drawArc(dotDrawRect, 120, progress * 3, false, prPaint);

    }
           

4,如果需要和使用者互動,還需要處理觸摸、點選這些事件(以後再仔細分析)

源碼:http://git.oschina.net/hanbingsheshou/SimpleDraw

從Android繪制View小例子中深入了解自定義View

繼續閱讀