View的Layout过程

View的Layout过程的作用是计算View的位置,即Left,top,right和bottom四个顶点的位置。

1.View的Layout过程

代码

 public void layout(int l, int t, int r, int b) {
        ...
        boolean changed = isLayoutModeOptical(mParent) ?
                setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);

        if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
            onLayout(changed, l, t, r, b);
    }
    ...
}

调用setFrame()方法,将传入的四个位置值,设为View的四个顶点的位置,代码如下。setOptialFrame()方法中实际上也是调用了setFrame()。

protected boolean setFrame(int left, int top, int right, int bottom) {
    ...
    mLeft = left;
    mTop = top;
    mRight = right;
    mBottom = bottom;

    mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);

    }

View的onLayout()方法是个空实现,因为这个方法的作用是计算子View在父ViewGroup中的位置,而在View中是没有子View的。

 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    }

流程图

layout() -> setOpticalFrame()/setFrame() -> onLayout()

 

2.ViewGroup的Layout过程

代码

 public void layout(int l, int t, int r, int b) {
        ...
        boolean changed = isLayoutModeOptical(mParent) ?
                setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);

        if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
            onLayout(changed, l, t, r, b);
    }
    ...
}

流程与View的layout()过程相同,但ViewGroup的onLayout()方法是个抽象类,即自定义ViewGroup必须实现onLayout()方法!

重写的onLayout()方法一般有以下的代码步骤:

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

     // 1. 遍历所有子View
          for (int i=0; i<getChildCount(); i++) {
              View child = getChildAt(i);   

              // 2. 计算当前子View的四个位置值,也是自定义ViewGroup的关键

              // 3. 根据上述4个位置的计算值,传递给子View的layout()方法,接下来的流程即是View的layout过程
              child.layout(mLeft, mTop, mRight, mBottom);
          }
      }
  }

流程图

layout() -> setOpticalFrame()/setFrame() -> onLayout() -> child.layout()

 

layout()方法的的发起

ViewRootImpl -> performTraversals() ->performLayout -> layout(),这里的host代表的是顶层View即DecorView。

 private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
            int desiredWindowHeight) {
        ...
        
            host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
        ...
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值