美文网首页
自定义View之路(一)

自定义View之路(一)

作者: 宁静世界 | 来源:发表于2018-06-16 15:32 被阅读0次

为什么要学自定义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开始,从今天开始走上自定义疯狂学习之路。首先来一波最简单的圆的自定义。对于自定义View的...

  • Android自定义View(一)-2016-06-05

    关于自定义View,是Android学习的必经之路,个人觉得自定义View更重要的是关于绘图的计算算法,利用And...

  • 自定义View之路(一)

    为什么要学自定义View,因为这是一个Android初级工程师到中高阶的必经之路,很多人对自定义View都比较恐惧...

  • 自定义View5---完整的自定义View

    移步自定义View系列 1.自定义view的分类自定义单一view(不含子view)继承view继承特定view如...

  • Android View(转)

    自定义View的原理自定义View基础 - 最易懂的自定义View原理系列自定义View Measure过程 - ...

  • 自定义View系列

    自定义View1---知识储备自定义View2---View Measure过程自定义View3---View L...

  • 自定义View

    自定义View系列文章 自定义View view向上滚动

  • 自定义View(一) 自定义View的概述

    不怕跌倒,所以飞翔 自定义View概述 1.自定义View分类 自定义View 直接继承View主要是绘制 自定义...

  • Android自定义View

    Android自定义View 参考:从此再有不愁自定义View——Android自定义view详解android ...

  • 通过圆形载入View了解自定义View

    这是自定义View的第一篇文章,通过制作简单的自定义View来了解自定义View的流程。自定义View是Andro...

网友评论

      本文标题:自定义View之路(一)

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