View的Layout过程

本文详细解析了Android中View和ViewGroup的布局过程,包括计算View的位置、View的layout方法流程、ViewGroup如何通过onLayout计算子View的位置等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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());
        ...
    }

 

回答: 你遇到的问题是找不到模块'C:\winD\毕设\面试准备\面试项目1\music-website-master\music-client\node_modules\webpack-dev-server\bin\webpack-dev-server.js'。根据提供的引用内容,我没有找到与你的问题直接相关的信息。引用\[1\]提到了关于Visual Studio的调试器的自定义设置,引用\[2\]提到了关于命令行参数的问题,引用\[3\]提到了一个关于Android平台加载失败的问题。根据这些信息,我无法直接回答你的问题。建议你检查路径是否正确,确保所需的模块存在于指定的位置。如果问题仍然存在,你可以尝试重新安装相关的模块或查找其他解决方案。 #### 引用[.reference_title] - *1* [Ogre 2.0 doc (slides) - Updated 1st dec 2012](https://blog.csdn.net/pizi0475/article/details/17655973)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Unreal Engine 4.14 Release Notes](https://blog.csdn.net/pizi0475/article/details/53185107)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值