美文网首页
Android View 绘制流程 ( 二 ) Layout

Android View 绘制流程 ( 二 ) Layout

作者: 是刘航啊 | 来源:发表于2020-12-30 11:05 被阅读0次
ViewRootImpl -> performTraversals
private void performTraversals() {
    ...
    performMeasure();
    performLayout();
    performDraw();
    ...
}
ViewRootImpl -> performLayout
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
            int desiredWindowHeight) {
    ...
    host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
    ...
}

host.layout() -> View.layout()

View -> layout
public void layout(int l, int t, int r, int b) {
    ...
     onLayout(changed, l, t, r, b);
    ...
}
View -> onLayout
/**
 * Called from layout when this view should
 * assign a size and position to each of its children.
 *
 * Derived classes with children should override 
 * this method and call layout on each of
 * their children.
 * @param changed This is a new size or position for this view
 * @param left Left position, relative to parent
 * @param top Top position, relative to parent
 * @param right Right position, relative to parent
 * @param bottom Bottom position, relative to parent
 */
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
}

Derived classes with children should override -> 当存在子类时应该重写
即当自定义 View 继承自 ViewGroup 时,需要重写 onLayout 方法

以 LinearLayout 为例子
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (mOrientation == VERTICAL) {
        layoutVertical(l, t, r, b);
    } else {
        layoutHorizontal(l, t, r, b);
    }
}
LinearLayout -> layoutVertical
void layoutVertical(int left, int top, int right, int bottom) {
    ...
    for (int i = 0; i < count; i++) {
        if (child == null) {
                childLeft += measureNullChild(childIndex);
        } else if (child.getVisibility() != GONE) {
            ...
            setChildFrame(child, childLeft, childTop + getLocationOffset(child),
                        childWidth, childHeight);
            childTop += childHeight + lp.bottomMargin + getNextLocationOffset(child);
            ...
        }
    }
    ...
}
LinearLayout -> setChildFrame
private void setChildFrame(View child, int left, int top, int width, int height) {
    child.layout(left, top, left + width, top + height);
}

在 visibility != GONE 的情况下会去摆放子 View 的位置。LinearLayout 会循环叠加 top
可以猜想一下 layoutHorizontal 方法就会叠加 left

LinearLayout -> layoutHorizontal
void layoutHorizontal(int left, int top, int right, int bottom) {
     ...
    for (int i = 0; i < count; i++) {
        if (child == null) {
                childLeft += measureNullChild(childIndex);
        } else if (child.getVisibility() != GONE) {
            ...
           setChildFrame(child, childLeft + getLocationOffset(child), childTop,
                        childWidth, childHeight);
            childLeft += childWidth + lp.rightMargin +
                        getNextLocationOffset(child);
            ...
        }
    }
    ...
}

和猜想的差不多

onLayout.jpg
总结

如果继承自 View 就不用实现 onLayout 方法,如果继承自 ViewGroup 就需要实现 onLayout 方法。Layout 流程是确定和摆放子 View 在父容器中的位置。

到这里 View 绘制流程 Layout 流程 到这里就介绍完了,如果有什么写得不对的,可以在下方评论留言,我会第一时间改正。

相关文章

网友评论

      本文标题:Android View 绘制流程 ( 二 ) Layout

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