Android getMeasuredWidth是0,导致更改屏幕大小界面组件不可见

本文解析了TextView在界面显示异常的问题,通常表现为即使已赋值但仍未显示。此现象源于View加载未完成导致getMeasuredWidth返回0。解决方案是在View.post中使用Runnable进行measure,确保View尺寸正确计算。

     更改屏幕大小显示后,TextView明明赋值了,却并不能在界面上显示的原因是getMeasuredWidth是0。出现这种情况多半是因为在测量之前View 还没加载完毕。因为View的Measure过程和Activity的生命周期方法不是同步执行的,所以无法保证Activity执行了onCreate()、onStart()、onResume()时某个View已经测量完毕了,如果View还没有测量完毕,那么获得宽/高就是0。

     这时候需要runnable写 getMeasuredWidth,并且getMeasuredWidth之前先mesure一下,就会发现虽然 getMeasuredWidth仍然是0,但是界面上TextView却变的可见了,代码如下:

mCardView.post(() -> {
            mCardView.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            mMyStationName.setMaxWidth(mCardView.getMeasuredWidth() - LayoutUtils.dpToPx(getContext(), 2 * STATION_NAME_LEFT_MARGIN));
            mMyStationName.invalidate();
        });

一个view的大小的最终确定是在onlayout中,但是当我们打开Activity,执行onCreate方法的时候,view可能还没执行到onlayout方法,这也是为什么我们在onCreate的方法中,通过getWidth获取的宽度为0的原因,但是在View.post方法中,实现了一个Runnable,即添加了一个队列任务,在执行完setContentView方法之后,队列任务里面会多一条询问布局是否完成的任务,我们添加的这一个任务就是加在这个任务之后,所以通过view.post这个方法可以获取到view的宽和高

Android 中,`getMeasuredWidth()` 方法在视图大小处理方面有重要作用。 ### 作用 `getMeasuredWidth()` 用于获取视图在测量阶段结束之后得到的原始测量宽度值。从源码上看,它获取的是 `mMeasuredWidth` 的值,这是一个 8 位的十六进制数字,高两位表示 measure 阶段的 Mode 值,而 `mMeasuredWidth & MEASURED_SIZE_MASK` 表示测量阶段结束之后视图真实的值,该值会在调用 `setMeasuredDimensionRaw()` 函数之后被设置[^3]。 ### 使用方法 `getMeasuredWidth()` 是 View 类的一个公共方法,使用时直接在 View 对象上调用即可。以下是一个简单的示例代码: ```java import android.os.Bundle; import android.view.View; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取 TextView 实例 TextView textView = findViewById(R.id.textView); // 为了确保测量完成,在布局完成后获取测量宽度 textView.post(new Runnable() { @Override public void run() { int measuredWidth = textView.getMeasuredWidth(); // 可以在这里使用 measuredWidth 进行后续操作 } }); } } ``` 在上述代码中,为了确保测量已经完成,使用了 `post()` 方法,该方法会将一个 `Runnable` 放入消息队列中,当视图完成布局后执行,此时调用 `getMeasuredWidth()` 可以获取到准确的测量宽度。 ### 原理 在 Android 的视图系统中,视图的绘制流程包含测量(measure)、布局(layout)和绘制(draw)三个阶段。`getMeasuredWidth()` 与测量阶段紧密相关。在测量阶段,系统会调用视图的 `onMeasure()` 方法来确定视图的大小。在 `onMeasure()` 方法中,通过调用 `setMeasuredDimension()` 或 `setMeasuredDimensionRaw()` 方法来设置测量的宽度和高度值,这些值会被存储在 `mMeasuredWidth` 和 `mMeasuredHeight` 中,之后就可以通过 `getMeasuredWidth()` 和 `getMeasuredHeight()` 方法获取这些测量值。例如 `HorizontalScrollView` 的 `onMeasure` 方法中,会对其子视图进行测量,在满足一定条件下会调用 `child.measure()` 方法来重新测量子视图的大小,并最终设置其测量宽度和高度[^4]。 ### 注意事项 - 要确保在测量阶段完成后调用 `getMeasuredWidth()` 方法,否则可能获取到的值准确。通常可以在 `onMeasure()` 方法之后或者使用 `post()` 方法来保证测量完成。 - 在非人为设置的情况下,`getWidth()` 获得的视图最终宽度与 `getMeasuredWidth()` 获得的视图测量宽度永远是相等的,但这并意味着它们在任何情况下都完全等同,因为在某些特殊情况下可以手动改变视图的最终宽度[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值