Android绘制流程

2017-03-16  本文已影响106人  theFullHorizon

相关知识点

LayoutParams

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

View的测量模式

View/ViewGroup的职责

View的职责

ViewGroup的职责

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

自定义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的相关类:

自定义控件优化

上一篇下一篇

猜你喜欢

热点阅读