为什么在onResume()中调用View的getWidth()方法会返回0?

9

根据我所阅读的资料,你不能在构造函数中调用getWidth()getHeight()方法来获取View的宽度或高度,但是我在onResume()方法中调用了这些方法。此时屏幕布局难道不应该已经绘制好了吗?

@Override
protected void onResume() {
    super.onResume();

    populateData();
}

private void populateData() {
    LinearLayout test = (LinearLayout) findViewById(R.id.myview);
    double widthpx = test.getWidth();
}
3个回答

5

当调用onResume()时,视图还没有被绘制,它的宽度和高度为0。您可以使用OnGlobalLayoutListener()来“捕获”其大小更改:

yourView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

    @Override
    public void onGlobalLayout() {

        // Removing layout listener to avoid multiple calls
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            yourView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
        else {
            yourView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }

        populateData();
    }
});

需要更多信息,请查看Android获取宽度返回0


2
谢谢,我喜欢一个可以复制粘贴的答案。 - William T. Mallard

5

在调用getWidthgetHeight之前,必须等待当前视图层次结构至少被测量,以便返回的值不为0。您可以获取“根”布局并发布一个可运行对象。在可运行对象内部,您应该能够成功地检索宽度和高度。

root.post(new Runnable() {
     public void run() {
         LinearLayout test = (LinearLayout) findViewById(R.id.myview);
         double widthpx = test.getWidth();
     }
});

1
这个可行...但如果您能解释为什么它可行,那就太好了! - Nerdy Bunz

0

正如之前的回答所述-您的视图尚未测量。请查看Jetpack下的Android KTX-Kotlin扩展,特别是这个:

View.doOnLayout((view: View) -> Unit)?)

这个扩展函数可以确保提供的操作在视图布局完成后执行,如果已经完成布局,则立即调用。

https://developer.android.com/reference/kotlin/androidx/core/view/package-summary#(android.view.View).doOnLayout(kotlin.Function1)

这篇文章详细解释了视图是如何被测量、布局和绘制的,以及作为开发者你可以做些什么来确保你的视图获得正确的大小。它还介绍了通常推荐的解决方案,例如 View.post() 和注册 OnGlobalLayoutListener,并解释了在使用它们时可能出现的问题。

https://cheesecakelabs.com/blog/understanding-android-views-dimensions-set/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接