自定义View之路(一)

为什么要学自定义View,因为这是一个Android初级工程师到中高阶的必经之路,很多人对自定义View都比较恐惧,包括我自己,学好自定义View需要花费较多时间和精力,但是请不要畏惧,你必须面对,迈过这座大山,你会有不一样的感觉,下面整理了一些自己在学习自定义View的笔记.

当然,自定义View其实也可以很好玩,如果让你自定义View你第一个想绘制的是什么,嗯?那就画一个你想到的东西放松一下吧
思考:生活中绘画是什么样子的呢?让我们想一下需要准备的东西和过程

首先你需要一个画板,画纸,颜料,画笔,嗯没错,你最少需要这些东西

那么在程序中呢?其实也是一样的

1,首先我们定义一个类继承View重写他的onMeasure和onDraw方法
onMeasure中我们要定义画板的大小,
2,onDraw开始绘画,他提供了一个Canvas也就是画板,这个画板的大小是我们之前定义的(onMeasure后的)
有了画板我们还需要什么呢,一支笔Paint,你可以选择任意一种笔,粗的或者细的,红的或者蓝的,

开始涂鸦作画
image.png

需要掌握的

//获取测量模式
 int specMode = MeasureSpec.getMode(measureSpec);
//获取测量大小
int specSize = MeasureSpec.getSize(measureSpec);
//EXACTLY:表示设置了精确的值,一般当childView设置其宽、高为精确值、match_parent时,ViewGroup会将其设置为EXACTLY;
//AT_MOST:表示子布局被限制在一个最大值内,一般当childView设置其宽、高为wrap_content时,ViewGroup会将其设置为AT_MOST;
//UNSPECIFIED:表示子布局想要多大就多大,一般出现在AadapterView的item的heightMode中、ScrollView的childView的heightMode中;

//设置测量后的大小
 setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
//画方
 canvas.drawRect(RectF rect, Paint paint)
//画圆
 canvas.drawOval(float left, float top, float right, float bottom, Paint paint)
//画路径
canvas.drawPath(Path path, Paint paint);
等等...

完整的代码

public class DiyView01 extends View {

    private Paint mMouthPaint;
    private Paint mBodyPaint;

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

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

    public DiyView01(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        /**
         * 获得绘制文本的宽和高
         */
        mMouthPaint = new Paint();
        mMouthPaint.setColor(Color.GRAY);
        mBodyPaint = new Paint();
        mBodyPaint.setColor(getContext().getResources().getColor(R.color.colorGreen));
        mBodyPaint.setAntiAlias(true);
        mBodyPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mBodyPaint.setStrokeWidth(10);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.RED);      //设置canvas的背景色
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //画圆   float left, float top, float right, float bottom
            RectF rectF = new RectF(80, 280 + (500 - 280) / 2, 600, 1100);
            canvas.drawRect(rectF, mBodyPaint);

            //画方  颜色是分层次的,第二层能够覆盖第一层的颜色
            canvas.drawOval(80, 280, 600, 500, mMouthPaint);

            Path path = new Path();
            //移动到
            path.moveTo(600, 500);
            //画线并移动到
            path.lineTo(500, 540);
            //画曲线
            path.quadTo(1200, 900, 600, 900);
            path.lineTo(600, 940);
            path.quadTo(1200, 900, 600, 500);
            //关闭
            path.close();
            //画路径
            canvas.drawPath(path, mBodyPaint);
        }
    }

    private int measureWidth(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        int result = 0;

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = specSize;
//            result = 200;
            if (specMode == MeasureSpec.AT_MOST) {
                result = result < specSize ? result : specSize;
            }
        }
        return result;
    }

    private int measureHeight(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        int result = 0;

        if (specMode == MeasureSpec.EXACTLY) {
            return specSize;
        } else {
            result = specSize;
//            result = 200;
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }
}

你可能感兴趣的:(自定义View之路(一))