美文网首页
Android绘制流程

Android绘制流程

作者: theFullHorizon | 来源:发表于2017-03-16 11:28 被阅读106次

    相关知识点

    LayoutParams

    每个自定义的ViewGroup都需要确定添加的子View能够拥有什么样的属性,如MarginLayoutParams,可以通过ViewGroup的generateLayoutParams()方法来自定义ViewGroup的LayoutParams。从这里我们也可以理解,当我们在代码中动态生成布局的时候,父控件如果是LinearLayout,则子控件设置的LayoutParams必须是LinearLayout.LayoutParams。

    View的测量模式

    • EXACTLY:表示设置了精确的值,一般当childView设置其宽、高为精确值、match_parent时,ViewGroup会将其设置为EXACTLY;
    • UNSPECIFIED:表示子布局想要多大就多大,一般出现在AadapterView的item的heightMode中、ScrollView的childView的heightMode中;此种模式比较少见。
    • AT_MOST:表示子布局被限制在一个最大值内,一般当childView设置其宽、高为wrap_content时,ViewGroup会将其设置为AT_MOST。这种模式下,一般我们要测量控件的实际大小。

    View/ViewGroup的职责

    View的职责

    • 根据ViewGroup建议的宽高和测量模式计算出自己的宽高
    • 在ViewGroup中制定的区域内绘制自己
    • 所以自定义ViewGroup更多的是在onMeasure(),onDraw()中处理
      注意自定义View更多的是考虑padding值

    ViewGroup的职责

    • 给childView计算出建议的宽高和测量模式
    • 决定childView的位置
    • 所以自定义ViewGroup更多的是在onMeasure(),onLayout()中处理,onDraw()交由系统处理
      注意自定义ViewGroup更多的是考虑children的margin

    自定义控件绘制的一般流程

    自定义View绘制流程

    1. 在onMeasure()中测量自身,主要针对warp_content来测量自己。如果你设计的控件是Match_Parent或是制定的值,则onMeasure()可以省略。
    2. 根据测量的结果在onDraw()中绘制自己

    注意,当自定义的View的宽高是Match_parent , 或者具体值的话,则不用复写onMeasure()

    自定义ViewGroup绘制流程

    1. 根据childView需要支持的属性自定义LayoutParams
       @Override
       protected LayoutParams generateDefaultLayoutParams()    {
            return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        }
        public LayoutParams generateLayoutParams(AttributeSet attrs)    {
            return new MarginLayoutParams(getContext(), attrs);
        }
        protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p)    {
            return new MarginLayoutParams(p);
        }
    
    1. onMeasure()中调用measureChildren()来使childView测量自己。如果onMeasure()中测量模式是wrap_content,则需要根据childView的测量结构来决定ViewGroup自己的大小
      //设定自定义View或者ViewGroup在onMeasure()测量的宽高
      setMeasuredDimension(w,h)方法来设定。
      //根据spec(父容器onMeasure提供的宽值),子控件支持的padding,以及子控件自身的大小
      计算出子控件的MeasureSpec类型的值,这个值计算出之后一般就要调用childView.measre().
      getChildMeasureSpec(int spec, int padding, int childDimension)

    2. onLayout中通过childView.layout(cl, ct, cr, cb)来设定childView的布局位置。
      如果子控件支持margin则,计算位置的时候主语考虑margin
      其中的自View的区域通过子View的对应LayouParams(如MarginLayoutParams)来获取自定义ViewGroup的相关类:

    自定义控件优化

    • onMeasure(),onLayout(),onDraw()不宜使用局部变量

    相关文章

      网友评论

          本文标题:Android绘制流程

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