为啥在 onResume() 中对 View 调用 getWidth() 返回 0?

Posted

技术标签:

【中文标题】为啥在 onResume() 中对 View 调用 getWidth() 返回 0?【英文标题】:Why does calling getWidth() on a View in onResume() return 0?为什么在 onResume() 中对 View 调用 getWidth() 返回 0? 【发布时间】:2014-05-23 05:08:40 【问题描述】:

我读到的所有内容都表明您不能在构造函数中的 View 上调用 getWidth()getHeight(),但我在 onResume() 中调用它们。到时候屏幕的布局不应该已经画好了?

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

    populateData();


private void populateData() 
    LinearLayout test = (LinearLayout) findViewById(R.id.myview);
    double widthpx = test.getWidth();

【问题讨论】:

【参考方案1】:

调用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 get width returns 0。

【讨论】:

谢谢,我爱我一个可以剪切和粘贴的答案。【参考方案2】:

您必须等待当前视图的层次结构至少在getWidthgetHeigth 返回一些东西之前测量!= 0。您可以做的是检索“根”布局并发布一个可运行的。在 runnable 中,您应该能够成功检索宽度和高度

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

【讨论】:

这行得通....但如果你能解释为什么这行得通,那就太好了!【参考方案3】:

正如之前的答案所述 - 您的观点尚未衡量。看看 Android KTX - Jetpack 下的 Kotlin 扩展,尤其是这个:

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

这个扩展函数确保一旦视图被布局,所提供的动作就会被执行,或者,如果它已经被布局,它将被立即调用。

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

本文详细解释了如何测量、放置和绘制 View,以及作为开发人员可以做些什么来确保获得正确的 View 大小。它还介绍了通常推荐的解决方案,例如View.post() 和注册OnGlobalLayoutListener,并解释了使用它们时可能出现的问题。

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

【讨论】:

以上是关于为啥在 onResume() 中对 View 调用 getWidth() 返回 0?的主要内容,如果未能解决你的问题,请参考以下文章

Android 必知必会:自定义 View 可以知道 onPause/onResume 被调用了吗?

Android 必知必会:自定义 View 可以知道 onPause/onResume 被调用了吗?(不依赖Lifecycle)

为啥 RequireView() 不返回视图 onResume()?

Android View onResume 方法?

android的adapter能不能在onResume方法中创建

Android - 如何访问在 onResume 中的 onCreate 中实例化的 View 对象?