自定义View步骤总结

为什么要自定义控件?
1,对自己的app特定的,独一无二的控件展示,来契合自己app的主风格
2,处理特特有的用户交互,比如点击一段英文文本,然后依据用户点击的单词给出响应,可以弹出此单词的发音和释义
3,优化布局,比如我的app中要做很多个switchButton,进行一个封装,优化布局,减少嵌套

自定义控件的流程和步骤是什么?
1,自定义属性的声明与获取
2,测量onMeasure
3,布局onLayout(ViewGroup)
4,绘制onDraw
5,onTouchEvent
6,onInterceptTouchEvent
大致分为以上6步,接下里简单说一下这6个步骤

<1>自定义属性的声明与获取:
1,分析需要自定义的属性都有什么,以及是什么样的自定义名称和自定义的属性的值.有color,string,dimension,reference,enum等等
2,分析好之后在res/value/新建attrs.xml中定义和声明
3,在layout xml文件中进行使用,定义view的宽高以及自定义属性的值
4,在View的构造方法中进行获取,通过typedArray a=context. obtainStyledAttributes进行获取.

<2>测量onMeasure
1,自定义View需要测量自身的大小以及自身到底是个什么样子,View测量,其父容器测量子View通过次方法,测量View由两个数字来决定,一个是测量的模式,一个是测量的值.测量的模式分为三种:
(1),EXACTLY,是我们设置了一个明确的值,比如说,宽100dp,高50dp.

/**
     * widthMeasureSpec, heightMeasureSpec这两个参数是从哪里来的?
     * onMeasure()函数由包含这个View的具体的ViewGroup调用,因此值也是从这个ViewGroup中传入的。
     * 子类View的这两个参数,由ViewGroup中的layout_width,layout_height和padding以及View自身的layout_margin共同决定。
     * 权值weight也是尤其需要考虑的因素,有它的存在情况可能会稍微复杂点。
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //此处我们测量View的宽度,先声明为0;
        int result = 0;
        //获得View的模式为三种模式的哪一种
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        //获得View的size
        int size = MeasureSpec.getSize(widthMeasureSpec);
        //如果View的模式为EXACTLY,就是我们设置了一个明确的值,比如说,宽100dp,那直接赋值即可
        if (mode == MeasureSpec.EXACTLY){
            result = size;
        }else{
            //如果自定义的View的尺寸不是明确的值的话,也就是模式为AT_MOST或者UNSPECIFIED
            //那么View的宽高就需要自己获得自己的宽度
            result = "需要的高度"+getPaddingLeft()+getPaddingRight();
            if (mode == MeasureSpec.AT_MOST){
                //如果模式为AT_MOST的话,View的最大不能超过父控件传下来的size的值
                result = Math.min(result,size);
            }
        }
    }

(2) AT_MOST, 是View最多不能超过某个值. 一般出现在我们设置View的大小为wrap _ content时,意味View的大小是由自身的内容去匹配的,并且最大的尺寸不能超过父容器的宽度或者高度..

(3),UNSPECIFIED, 是View 没有限制,多大多宽多高都可以,主要用于scrollView和listView中去,

2,MeasureSpec 是一个辅助类, View的测量是由模式和值来决定的,模式和值一般会封装MeasureSpec中,由View的父控件传递下来..通过此类去获得View的mode和size.

3,测量完毕之后, 需要调用setMeasureDimension来把最终测量的结果传递进去

4,requestLayout(); 当一个textView中的文本发生变化的时候,此View需要重新测量,调用requestLayout方法来重新测量..此方法不包括重新绘制..

<3>布局onLayout(viewGroup)
继承自ViewGroup的时候需要重写此方法,来决定子View的位置,

@Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() == GONE){
                continue;
            }

            //计算left,top,right,bottom的值
            child.layout(l,t,r,b);

            //出发onlayout 也调用requestLayout
        }
    }

<4>onDraw , 绘制自身显示的样子.
1,绘制的是内容区域的.
2,如果测量值,属性发生变化,重新绘制, invalidate()–主线程.postinvalidate()–子线程
3,Canvas.drawXXX
4,translate rotate scale skew 等画布的状态
5,save restore 保存状态

<5>onTouchEvent
1,ACTION_DOWN
ACTION_UP
ACTION_MOVE
2,ACTION_POINTER_DOWN
ACTION_POINTER_UP
多点触控

唉,还有很多很多…知识的海洋??哈哈,我笑了,应该是知识的宇宙,要学习的东西永远都是那么那么多…兴趣才是关键…加油..

本篇博客整理自鸿洋大神慕课网视频..

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值