Android自定義View實現八卦圖效果

最近研究了下自定義View,就自己寫了個Demo練練手。網上有很多講自定義View實現的文章,我這里就不說了,直接上Demo。


先看下效果

八卦圖.png

實現思路

1、左右兩邊分別畫一個背景為黑色和白色的半圓。
2、上下畫兩個小圓
3、最后畫魚眼

實現步驟

1、設置自定義屬性

     
    //這里我們設置了兩個屬性,一個是背景色,另一個是八卦的半徑
    <declare-styleable name="BaGuaView">
        <attr name="bgColor" format="color"></attr>
        <attr name="radius" format="integer"></attr>
    </declare-styleable>

2、定義畫筆和其他屬性

    /**
     * 黑色畫筆
     */
    private Paint mBlackPaint;

    /**
     * 白色畫筆
     */
    private Paint mWhitePaint;

    /**
     * 背景顏色
     */
    private int mBgColor;

    /**
     * 八卦半徑
     */
    private int mRadius;

3、初始化畫筆

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

    public BaGuaView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BaGuaView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BaGuaView, defStyleAttr, 0);

        try {
            mBgColor = array.getColor(R.styleable.BaGuaView_bgColor, Color.GRAY);//默認為棕色
            mRadius = array.getInteger(R.styleable.BaGuaView_radius, 100);//默認半徑為100
        } finally {
            array.recycle();
        }

        mWhitePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBlackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mWhitePaint.setColor(Color.WHITE);
        mBlackPaint.setColor(Color.BLACK);
    }

4、畫兩個半圓

    //將Canvas坐標移動到畫布中心
    canvas.translate(getWidth() / 2, getHeight() / 2);
    //設置背景色
    canvas.drawColor(mBgColor);

    //設置繪制區域,這里是以畫布中心為坐標原點
    RectF rectF = new RectF(-mRadius, -mRadius, mRadius, mRadius);
    //畫左邊黑色半圓
    canvas.drawArc(rectF, 90, 180, true, mBlackPaint);
    //畫右邊白色半圓
    canvas.drawArc(rectF, -90, 180, true, mWhitePaint);

效果如下


八卦1.png

5、繪制兩個魚頭

    //圓心分別上下移動半徑的一半,半徑為原來的一半
    canvas.drawCircle(0, -mRadius / 2, mRadius / 2, mBlackPaint);
    canvas.drawCircle(0, mRadius / 2, mRadius / 2, mWhitePaint);

效果如下

八卦2.png

6、繪制魚眼

    //畫兩個更小的圓,還以魚頭的圓心為圓心,半徑為原半徑的1/6,這個值可以自己設定
    canvas.drawCircle(0, -mRadius / 2, mRadius / 6, mWhitePaint);
    canvas.drawCircle(0, mRadius / 2, mRadius / 6, mBlackPaint);

效果如下

八卦3.png

7、讓八卦轉動起來

    //設置旋轉角度
    private float degrees = 0;

    //設置完背景色之后讓Canvas旋轉
    degrees = degrees + 3;
    canvas.rotate(degrees);
    
    //在八卦繪制完成之后每隔15ms刷新繪制,實現旋轉效果
    postInvalidateDelayed(15);

這樣我們就通過自定義View實現了八卦圖的功能。是不是很酷炫呀。

完整代碼

public class BaGuaView extends View {

    /**
     * 黑色畫筆
     */
    private Paint mBlackPaint;

    /**
     * 白色畫筆
     */
    private Paint mWhitePaint;

    /**
     * 背景顏色
     */
    private int mBgColor;

    /**
     * 八卦半徑
     */
    private int mRadius;



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

    public BaGuaView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BaGuaView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BaGuaView, defStyleAttr, 0);

        try {
            mBgColor = array.getColor(R.styleable.BaGuaView_bgColor, Color.GRAY);//默認為棕色
            mRadius = array.getInteger(R.styleable.BaGuaView_radius, 100);//默認半徑為100
        } finally {
            array.recycle();
        }

        mWhitePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBlackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);


        mWhitePaint.setColor(Color.WHITE);
        mBlackPaint.setColor(Color.BLACK);
    }


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

        int width = 0;
        int height = 0;

        //設定寬度
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        if (widthMode == MeasureSpec.EXACTLY) {
            width = getPaddingLeft() + getPaddingRight() + widthSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            width = getPaddingLeft() + getPaddingRight() + mRadius * 2;
        }

        //設定高度
        int heightMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(widthMeasureSpec);
        if (heightMode == MeasureSpec.EXACTLY) {
            height = getPaddingBottom() + getPaddingTop() + heightSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            height = getPaddingBottom() + getPaddingTop() + mRadius * 2;
        }

        setMeasuredDimension(width, height);


    }

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

    //設置旋轉角度
    private float degrees = -5;

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



        //將Canvas坐標移動到畫布中心
        canvas.translate(getWidth() / 2, getHeight() / 2);
        //設置背景色
        canvas.drawColor(mBgColor);

        //設置完背景色之后讓Canvas旋轉
        degrees = degrees + 5;
        canvas.rotate(degrees);

        //設置繪制區域,這里是以畫布中心為坐標原點
        RectF rectF = new RectF(-mRadius, -mRadius, mRadius, mRadius);
        //畫左邊黑色半圓
        canvas.drawArc(rectF, 90, 180, true, mBlackPaint);
        //畫右邊白色半圓
        canvas.drawArc(rectF, -90, 180, true, mWhitePaint);

        //繪制兩個小圓
        canvas.drawCircle(0, -mRadius / 2, mRadius / 2, mBlackPaint);
        canvas.drawCircle(0, mRadius / 2, mRadius / 2, mWhitePaint);
//
        //繪制兩個魚眼,畫兩個更小的圓,還以剛魚頭的圓心為圓心,半徑為原半徑的1/6,這個值可以自己設定
        canvas.drawCircle(0, -mRadius / 2, mRadius / 6, mWhitePaint);
        canvas.drawCircle(0, mRadius / 2, mRadius / 6, mBlackPaint);
        
        //每隔15ms刷新
        postInvalidateDelayed(15);
    }

}

項目地址https://github.com/xingchenfengn/CustomBaGuaView.git

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,263評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,229評論 4 61
  • 2017.6.14. 星期三 天氣:雨 自從加入巴厘島特種兵訓練營培訓后,聽老師講不同的精彩課程,每天都...
    FAB菲菲閱讀 382評論 0 0
  • 酒喝桿桿酒, 肉吃坨坨肉。 阿龍真英雄, 阿妞大美人。 女子皆羞澀, 男兒多血性。 聚會喜歌舞, 個個好嗓音。
    光速太慢閱讀 362評論 0 1
  • 我是一名高中生 喜歡傷春悲秋,偶爾也愛文藝,最熱衷的是討論各種熱播青春劇。最喜歡學習數學,卻總是考的不好。喜歡寫文...
    想上一本的孩紙閱讀 130評論 0 1