返回介绍

2.1 Measure

发布于 2024-12-23 22:19:58 字数 2249 浏览 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 尺寸。

发布评论

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