Android自定义View - ViewGroup

308 阅读1分钟

除了自定义View外,有时我们也会自定义一个ViewGroup。自定义ViewGroup和自定义View的区别在于,自定义View主要重写onMeasure和onDraw,而自定义ViewGroup则主要重写onMeasure和onLayout。

onMeasure和自定义View的类似,但除了测量自己外,还要测量它的子控件,而测量子控件我们通常使用measureChild()或measureChildren()方法。然后在onDraw中调用drawChild()方法,将所有子控件绘制到自己上面。然后在onLayout中调用子控件的layout()方法将所有子控件的位置确定下来。补充下,使用view.measure()和view.draw()方法也可以完成这个过程,只不过使用measureChild()和drawChild()这一组方法更便捷。无论你使用哪种方式测量和绘制子控件,最终你都是在onLayout()方法中调用layout()方法将子控件布局到容器中。我们总结一下流程:

  1. 测量子控件(onMeasure中measureChild或view.measure)
  2. 将子控件绘制在容器上(onDraw中drawChild或view.draw)
  3. 将子控件布局在容器上(onLayout中view.layout)

另外,如果你需要在容器上再添加一些绘制,你可以重写dispatchDraw()方法,而不是onDraw()方法,比如在ScrollView上绘制页面的编号等等。

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
}

如果你调用viewGroup的requestLayout()方法,就会回调onLayout()方法,而如果你调viewGroup的invalidate()方法,也会回调onLayout()方法,同时也会重绘子控件。如果你不想重绘子控件,则你应该调用requestLayout()方法,提供更好的性能。