【问题标题】:getHeight() of layout returns zero by ViewTreeObserver布局的 getHeight() 由 ViewTreeObserver 返回零
【发布时间】:2017-09-29 15:22:13
【问题描述】:

我在 OnCreate 方法中使用 ViewTreeObserver 来获取工具栏和底部布局的高度,但我仍然得到 0 高度,为什么?我是不是做错了什么?

我是这样称呼的:

ViewTreeObserver viewTreeObserver = toolbar.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
            @Override
            public void onGlobalLayout() {
                // Ensure you call it only once :
                toolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                height1 = toolbar.getMeasuredHeight();
            }
        });

        final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.bottom);
        ViewTreeObserver vto = linearLayout.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
            @Override
            public void onGlobalLayout() {
                // Ensure you call it only once :
                linearLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                height2 = linearLayout.getMeasuredHeight();

            }
        });

        Toast.makeText(getApplicationContext(), String.valueOf(height1) + String.valueOf(height2), Toast.LENGTH_SHORT).show();

【问题讨论】:

  • 您是否尝试过 getWidth() 或 getHeight() 与处理程序?这是示例: new Handler().postDelayed( new Runnable() { @Override public void run() { height1 = toolbar.getMeasuredHeight(); height2 = linearLayout.getMeasuredHeight(); } }, 1000 );
  • 我也试过这个,但没有解决方案。
  • 如果布局高度为 0 怎么办?你确定布局是可见的吗?我问这个是因为我之前在我的项目中错过了这个。
  • 是的,布局是可见的,我从 xml 中给出了固定高度,关闭屏幕后,我得到了布局的价值,但在活动开始时没有。
  • 如果你想在屏幕关闭时获取布局高度,这意味着活动处于onPause状态。所以所有布局的高度都是0。我理解错了吗?

标签: android


【解决方案1】:

看起来您的布局必须进行多次测量/布局传递,并且在第一次传递后布局的各个部分的尺寸为零。仅当您有正尺寸时才尝试删除OnGlobalLayoutListener。像这样的:

if (linearLayout.getMeasuredHeight() > 0) {
    linearLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}

【讨论】:

  • 删除 OnGlobalLayoutListener 是什么意思?我必须直接获得高度吗?如果是这样,那么我没有任何价值。
  • 我喜欢这个但没有解决方案:@Override public void onGlobalLayout() { if (linearLayout.getMeasuredHeight() > 0) { height2 = linearLayout.getMeasuredHeight(); linearLayout.getViewTreeObserver().removeOnGlobalLayoutListener((ViewTreeObserver.OnGlobalLayoutListener) this); } }
【解决方案2】:

我也遇到过同样的问题,但是原因和@aga 的回答不一样。问题是在初始化活动时(在 onCreate 内),我的视图被隐藏了。我只是在布局大小计算完成后移动显示/隐藏我的视图的代码,以使其按预期工作。希望这能有所帮助。

【讨论】:

    【解决方案3】:

    OnGlobalLayoutListenerViewTreeObserver 上工作,它的方法onGlobalLayout 不会立即调用。此侦听器仅适用于当前布局中发生的某些事件(当向侦听器显示某些更改时)。因此,当您加载布局时,您会得到 0 高度

    如果你想在 ViewTreeObserver 之外访问这个值,解决方案是这样的:

    private int height;
    
    ViewTreeObserver viewTreeObserver = toolbar.getViewTreeObserver();
    viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            height = toolbar.getMeasuredHeight();
            setHeight(height);
            // Ensure you call it only once :
            toolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    });
    
    private void setHeight(int h) {
        this.height = h;
        Toast.makeText(getApplicationContext(), String.valueOf(height), Toast.LENGTH_SHORT).show();
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-02
      • 2012-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-02
      相关资源
      最近更新 更多