返回介绍

1.10 onMeasure 测量

发布于 2024-12-23 21:07:34 字数 1916 浏览 0 评论 0 收藏 0

查看了下 onMeasure ,发现有个地方还是比较在意的。 当 isIconified() 返回 false 的时候,width 的 mode 在最后都会被设置成 MeasureSpec.EXACTLY 。 在 SearchView 伸展收缩的时候, onMeasure 会被执行多次,width 根据其 mode 改变,之后 mode 设置为 EXACTLY 再调用父类 super 方法进行测量。

设置为 EXACTLY,这样父控件就能确切的决定 view 的大小,那为什么只对 width 而不对 height 进行设置呢?

通过查看默认的 layout , 可以看到主要组件的 layout_height 的大多都是 match_parent(对应 EXACTLY 模式),而 layout_width 基本都是 wrap_content(对应 AT_MOST 模式)。 另外,不是只有伸展收缩的时候, onMeasure 才会被执行,点击语音搜索按钮/输入框获取焦点的时候/...也会执行。

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // Let the standard measurements take effect in iconified state.
    if (isIconified()) {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      return;
    }

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);

    switch (widthMode) {
      case MeasureSpec.AT_MOST:
        // If there is an upper limit, don't exceed maximum width (explicit or implicit)
        if (mMaxWidth > 0) {
          width = Math.min(mMaxWidth, width);
        } else {
          width = Math.min(getPreferredWidth(), width);
        }
        break;
      case MeasureSpec.EXACTLY:
        // If an exact width is specified, still don't exceed any specified maximum width
        if (mMaxWidth > 0) {
          width = Math.min(mMaxWidth, width);
        }
        break;
      case MeasureSpec.UNSPECIFIED:
        // Use maximum width, if specified, else preferred width
        width = mMaxWidth > 0 ? mMaxWidth : getPreferredWidth();
        break;
    }
    widthMode = MeasureSpec.EXACTLY;
    super.onMeasure(MeasureSpec.makeMeasureSpec(width, widthMode), heightMeasureSpec);
  }

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

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

发布评论

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