返回介绍

2.1 Measure

发布于 2024-12-23 22:19:58 字数 2249 浏览 0 评论 0 收藏 0

最直接的就是看代码,如果不喜欢,可以跳过代码看总结。:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   prepareChildren(); /* 解析依赖关系,并用 1.2 中提到的 Comparator 对 View 按依赖关系进行排序 */
   ensurePreDrawListener(); /* 若 PreDrawListener 未添加,则添加到 ViewTreeObserver */

   //...(省略代码) 解析 paddingmeasureSpec

   final int childCount = mDependencySortedChildren.size();
   for (int i = 0; i < childCount; i) {
     final View child = mDependencySortedChildren.get(i);
     final LayoutParams lp = (LayoutParams) child.getLayoutParams();

		//...(省略代码) 处理 keyline

     int childWidthMeasureSpec = widthMeasureSpec;
     int childHeightMeasureSpec = heightMeasureSpec;

		//...(省略代码) 处理由于 fitSystemWindows 带来的 padding

		/* 如果 childView 有 Behavior 并且它的 onMeasureChild 返回 true,则由 behavior 来对 childView 进行 measure,否则就自己 measure. */
     final Behavior b = lp.getBehavior();
     if (b == null || !b.onMeasureChild(this, child, childWidthMeasureSpec, keylineWidthUsed,
         childHeightMeasureSpec, 0)) {
       onMeasureChild(child, childWidthMeasureSpec, keylineWidthUsed,
           childHeightMeasureSpec, 0);
     }

		/* 取最大的 child width/height 加上 margin 作为已经消耗的尺寸。 */
     widthUsed = Math.max(widthUsed, widthPadding  child.getMeasuredWidth()
         lp.leftMargin  lp.rightMargin);
     heightUsed = Math.max(heightUsed, heightPadding  child.getMeasuredHeight()
         lp.topMargin  lp.bottomMargin);

     childState = ViewCompat.combineMeasuredStates(childState,
         ViewCompat.getMeasuredState(child));
   }

	/* 设置自身的 measure 尺寸 */
   final int width = ViewCompat.resolveSizeAndState(widthUsed, widthMeasureSpec,
       childState & ViewCompat.MEASURED_STATE_MASK);
   final int height = ViewCompat.resolveSizeAndState(heightUsed, heightMeasureSpec,
       childState << ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
   setMeasuredDimension(width, height);
}

总结下来,onMeasure 干了这么几件事:

  1. 根据依赖关系对所有子 View 进行排序
  2. 保证 OnPreDrawListener 被添加
  3. 按依赖关系遍历子 View:
    • 如果子 View 有 Behavior,并且它的 onMeasureChild 返回 true,则使用 Behavior 进行 measure;否则直接使用 measureSpec 对子 View 进行 measure;
    • 取子 VIew 最大的 measure 尺寸为已使用的 measure 尺寸。
  4. 更新本身的 Measure 尺寸。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文