Android自定義View實(shí)現(xiàn)八卦圖效果

最近研究了下自定義View,就自己寫了個(gè)Demo練練手。網(wǎng)上有很多講自定義View實(shí)現(xiàn)的文章,我這里就不說了,直接上Demo。


先看下效果

八卦圖.png

實(shí)現(xiàn)思路

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

實(shí)現(xiàn)步驟

1、設(shè)置自定義屬性

     
    //這里我們?cè)O(shè)置了兩個(gè)屬性,一個(gè)是背景色,另一個(gè)是八卦的半徑
    <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);//默認(rèn)為棕色
            mRadius = array.getInteger(R.styleable.BaGuaView_radius, 100);//默認(rèn)半徑為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、畫兩個(gè)半圓

    //將Canvas坐標(biāo)移動(dòng)到畫布中心
    canvas.translate(getWidth() / 2, getHeight() / 2);
    //設(shè)置背景色
    canvas.drawColor(mBgColor);

    //設(shè)置繪制區(qū)域,這里是以畫布中心為坐標(biāo)原點(diǎn)
    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、繪制兩個(gè)魚頭

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

效果如下

八卦2.png

6、繪制魚眼

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

效果如下

八卦3.png

7、讓八卦轉(zhuǎn)動(dòng)起來

    //設(shè)置旋轉(zhuǎn)角度
    private float degrees = 0;

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

這樣我們就通過自定義View實(shí)現(xiàn)了八卦圖的功能。是不是很酷炫呀。

完整代碼

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);//默認(rèn)為棕色
            mRadius = array.getInteger(R.styleable.BaGuaView_radius, 100);//默認(rèn)半徑為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;

        //設(shè)定寬度
        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;
        }

        //設(shè)定高度
        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);
    }

    //設(shè)置旋轉(zhuǎn)角度
    private float degrees = -5;

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



        //將Canvas坐標(biāo)移動(dòng)到畫布中心
        canvas.translate(getWidth() / 2, getHeight() / 2);
        //設(shè)置背景色
        canvas.drawColor(mBgColor);

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

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

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

}

項(xiàng)目地址https://github.com/xingchenfengn/CustomBaGuaView.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容