解决Android onCreate中View高度为0的问题:三种测量方法

5星 · 超过95%的资源 需积分: 50 90 下载量 27 浏览量 更新于2024-09-13 6 收藏 197KB DOCX 举报
在Android开发中,有时候我们需要动态获取View的宽高,尤其是在视图尚未完全加载或者测量尺寸时,直接在`onCreate()`方法中获取的高度和宽度可能会为0。这是因为Android系统在视图绘制前会进行一系列预处理,包括测量和布局。本文将介绍三种常见的方法来解决在初始化时无法获取到准确高度的问题。 1. 在`onMeasure()`方法中获取 当一个View被测量时,系统会调用`onMeasure()`方法,这是获取View大小的理想时机。例如,在提供的`MyImageView`类中,我们在`onMeasure()`方法中打印了调用时间,可以看到这个方法在视图尺寸确定后被调用。因此,可以在`onMeasure()`中计算并存储宽度和高度,例如: ```java @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int measuredWidth = MeasureSpec.getSize(widthMeasureSpec); int measuredHeight = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(measuredWidth, measuredHeight); // 记录或设置视图的实际高度和宽度 int height = measuredHeight; // ... } ``` 2. 利用`postponeInvalidateOnMeasure()`方法 如果你的View需要在测量完成后获取大小,可以尝试使用`postponeInvalidateOnMeasure()`方法推迟测量过程,直到子视图布局完成。在`onMeasure()`结束后,再调用`invalidate()`来触发重新测量和绘制,此时高度值应该已经更新: ```java @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); invalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 在这里可以获取到正确的高度 int height = getHeight(); // ... } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // 在布局完成后的onLayout方法中,高度通常会得到正确的值 if (changed) { int height = getHeight(); // ... } } ``` 3. 监听`ViewTreeObserver`的变化 `ViewTreeObserver`提供了一种观察视图树变化的方法,通过`addOnGlobalLayoutListener()`可以监听到视图的尺寸变化。这将在视图布局完全完成后触发: ```java ViewTreeObserver observer = this.getViewTreeObserver(); observeraddOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override publicvoidonGlobalLayout() { int height = getHeight(); // 在这里高度已得到正确的值,可以进行后续操作 if (observer.isAlive()) { observerremoveGlobalLayoutListener(this); } } }); ``` 总结:获取View的高度和宽度并非一蹴而就,需要理解Android的测量和布局流程。在`onMeasure()`、`postponeInvalidateOnMeasure()`和`ViewTreeObserver`等方法中适时获取,可以确保在视图正确尺寸确定后获取到所需的值。根据具体场景选择合适的方法,避免在初始化阶段就试图获取零值。