Android自定义View实现八卦图效果

作者: 吾若成疯 | 来源:发表于2016-10-31 20:49 被阅读401次

    最近研究了下自定义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

    相关文章

      网友评论

      • IAMCJ:邢大神666
      • woitaylor:这不是太极图吗?
        吾若成疯:@woitaylor 对对对,我最近在看易经,所以叫他八卦☯:smile::smile::smile:

      本文标题:Android自定义View实现八卦图效果

      本文链接:https://www.haomeiwen.com/subject/xymputtx.html