自定义控件--View篇学习总结

学习android开发,我感觉自定义控件这个一定要好好的学习,这样能解决各式各样的需求。下面是我自己做的总结,写在这里方便以后复习吧。(看了好多的资料)

这里就先讲一下自定义View吧(感觉比较简单点相对于ViewGroup)

对于自定义View来说,就好像我们要在app上画一个自己想要的东西一样,先需要知道要画的东西的大小,然后进行绘制。
所以我们需要重写2个方法:
1.onMeasure()
2.onDraw()

onMeasure,就是测量,用来确定你想要View的大小,所以我们要重写View的onMeasure(),如下

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

虽然super.onMeasure()中会最终调用setMeasuredDimension()来为View设置宽高,但好像并不能正确的设置,所以需要我们自己亲自来设置比较靠谱
对于widthMeasureSpec,heightMeasureSpec这两个值我们可以用MeasureSpec对象将其拆分成Mode跟Size。Mode就是你在xml文件中对该控件的设置


match_parent or 精确值时(100dp) mode为EXACTLY
wrap_content 时 mode为 AT_MOST

于是,我们可以写个方法来准确测量传进来的widthMeasureSpec,heightMeasureSpec

/**
     * 重新测量宽度
     *
     * @param widthMeasureSpec
     * @return
     */
    private int measureWidth(int widthMeasureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = windowWidth; //我们自己期望的View的大小
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.max(result, specSize);
            }
        }
        return result;


     @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获取控件显示的高度宽度
        width = measureWidth(widthMeasureSpec);
        height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(width, height);

    }

测量好了之后就是绘制啦

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

这个就比较简单了,对着View的画板canvas随意的进行绘制就是啦
canvas.drawXXX()就行啦

这样一个自定义的View就做好啦

最后给一个大致的代码
java类

public class MyView extends View {

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

    public MyScrollTableLeftTitle(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        height = measureHeight(heightMeasureSpec);
        width = measureWidth(widthMeasureSpec);
        setMeasuredDimension(width , height);
    }

    /**
     * 重新测量高度
     *
     * @param heightMeasureSpec
     * @return
     */
    private int measureHeight(int heightMeasureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(heightMeasureSpec);
        int specSize = MeasureSpec.getSize(heightMeasureSpec);

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

    /**
     * 重新测量宽度
     *
     * @param widthMeasureSpec
     * @return
     */
    private int measureWidth(int widthMeasureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = getBlocWidth(); //自己期望的宽度
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.max(result, specSize);
            }
        }
        return result;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //代码省略
    }

}

xml里

  <包名.MyView
            android:layout_width="wrap_content"
            android:layout_height="100dp" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值