onMeasure
onMeasure会先测量父view根据父view的measureSpecSize测量出子view,由上向下的传递。onLayout一样先布局父view然后依次布局子view
看FrameLayout的onLayout方法
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
layoutChildren(left, top, right, bottom, false /* no force left gravity */);
}
调用layoutChildren方法
void layoutChildren(int left, int top, int right, int bottom,
boolean forceLeftGravity) {
final int count = getChildCount();
final int parentLeft = getPaddingLeftWithForeground();
final int parentRight = right - left - getPaddingRightWithForeground();
final int parentTop = getPaddingTopWithForeground();
final int parentBottom = bottom - top - getPaddingBottomWithForeground();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int width = child.getMeasuredWidth();
final int height = child.getMeasuredHeight();
int childLeft;
int childTop;
...
switch (verticalGravity) {
case Gravity.TOP:
childTop = parentTop + lp.topMargin;
break;
case Gravity.CENTER_VERTICAL:
childTop = parentTop + (parentBottom - parentTop - height) / 2 +
lp.topMargin - lp.bottomMargin;
break;
case Gravity.BOTTOM:
childTop = parentBottom - height - lp.bottomMargin;
break;
default:
childTop = parentTop + lp.topMargin;
}
child.layout(childLeft, childTop, childLeft + width, childTop + height);
}
根据child的layoutparam和gravity计算childTop和childLeft,然后调用child.layout()-->child.onLayout()布局child。一般viewGroup需要重写onLayout和onMeasure,view很少会需要重写。
ondraw
ondraw算是源码中最简单的方法了,只是传过来一个canvas,我们通过canvas来绘制。但是有算是最复杂的方法,因为在自定义一个view的时候更多的去重写ondraw方法。会重新写关于ondraw方法