自定義View合輯(4)-太極

leavesC發表於2019-05-05

為了加強對自定義 View 的認知以及開發能力,我計劃這段時間陸續來完成幾個難度從易到難的自定義 View,並簡單的寫幾篇部落格來進行介紹,所有的程式碼也都會開源,也希望讀者能給個 star 哈 GitHub 地址:github.com/leavesC/Cus… 也可以下載 Apk 來體驗下:www.pgyer.com/CustomView

先看下效果圖:

自定義View合輯(4)-太極

一、思路描述

繪製太極 View 的步驟分為以下幾步:

  • 繪製一個半徑為 radius 的空心圓
  • 將上半圓填充為黑色,下半圓填充為白色
  • 在穿過圓心的平行線上,繪製兩個填充色分別為黑白色,半徑為 radius/2 的圓
  • 在兩個小圓的圓心上再繪製兩個相反顏色,半徑更小的小圓

繪製過程還是蠻簡單的,總的程式碼也就一百行左右

二、原始碼

/**
 * 作者:leavesC
 * 時間:2019/4/26 9:29
 * 描述:
 */
public class TaiJiView extends BaseView {

    private Paint paint;

    public TaiJiView(Context context) {
        this(context, null);
    }

    public TaiJiView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

    private void initPaint() {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setDither(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = getSize(widthMeasureSpec, getResources().getDisplayMetrics().widthPixels);
        int height = getSize(heightMeasureSpec, getResources().getDisplayMetrics().heightPixels);
        width = height = Math.min(width, height);
        setMeasuredDimension(width, height);
    }

    private float radius;

    private float centerX;

    private float centerY;

    private float degrees;

    @Override
    protected void onSizeChanged(int w, int h, int oldW, int oldH) {
        w = w - getPaddingLeft() - getPaddingRight();
        h = h - getPaddingTop() - getPaddingBottom();
        w = Math.min(w, h);
        radius = w / 2f;
        centerX = getPaddingLeft() + radius;
        centerY = getPaddingTop() + radius;
    }

    private RectF rectF = new RectF();

    @Override
    protected void onDraw(Canvas canvas) {
        //稍稍留一點間距
        float realRadius = radius - 8;
        float temp1 = realRadius / 2f;
        float temp2 = temp1 / 8f;

        canvas.translate(centerX, centerY);
        canvas.rotate(degrees);

        //繪製邊框
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(0.4f);
        canvas.drawCircle(0, 0, realRadius, paint);

        //繪製左右半圓
        rectF.set(-realRadius, -realRadius, realRadius, realRadius);
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(0);

        paint.setColor(Color.BLACK);
        canvas.drawArc(rectF, 90, 180, true, paint);
        paint.setColor(Color.WHITE);
        canvas.drawArc(rectF, -90, 180, true, paint);

        //繪製上邊的白色圓
        canvas.save();
        canvas.translate(0, -temp1);
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(1);
        canvas.drawCircle(0, 0, temp1, paint);
        paint.setColor(Color.BLACK);
        canvas.drawCircle(0, 0, temp2, paint);
        canvas.restore();

        //繪製上邊的黑色圓
        canvas.save();
        canvas.translate(0, temp1);
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(0, 0, temp1, paint);
        paint.setColor(Color.WHITE);
        canvas.drawCircle(0, 0, temp2, paint);
        canvas.restore();
    }

    public float getDegrees() {
        return degrees;
    }

    public void setDegrees(float degrees) {
        this.degrees = degrees;
        postInvalidate();
    }

}

複製程式碼

相關文章