Android 开发问题:View 的 getWidth、getHeight 方法返回的值都为 0

java 复制代码
ImageView ivTest = findViewById(R.id.iv_test);

int width = ivTest.getWidth();
int height = ivTest.getHeight();

Log.i(TAG, "width: " + width);
Log.i(TAG, "height: " + height);
复制代码
# 输出结果

width: 0
height: 0
  • 在 Android 开发中,上述代码中,getWidth、getHeight 方法返回的值都为 0
问题原因
  1. 当一个 Activity 启动时,视图的创建和显示需要经过几个关键阶段:视图创建阶段 -> 测量阶段 -> 布局阶段 -> 绘制阶段

  2. 在 onCreate 或过早的阶段调用这些方法时,视图尚未完成测量和布局流程,因此坐标值尚未计算,默认返回 0

处理策略
  • 使用 View.post 方法,确保视图已完成布局
java 复制代码
ImageView ivTest = findViewById(R.id.iv_test);

ivTest.post(() -> {
    int width = ivTest.getWidth();
    int height = ivTest.getHeight();

    Log.i(TAG, "width: " + width);
    Log.i(TAG, "height: " + height);
});
补充学习
  • 在 onCreate 方法中,任何需要等待测量和布局阶段完成后才能确定的信息都无法获取,例如
  1. 尺寸相关方法:getWidth、getHeight、getMeasuredWidth、getMeasuredHeight
java 复制代码
ImageView ivTest = findViewById(R.id.iv_test);

int width = ivTest.getWidth();
int height = ivTest.getHeight();

int measuredWidth = ivTest.getMeasuredWidth();
int measuredHeight = ivTest.getMeasuredHeight();

Log.i(TAG, "width: " + width);
Log.i(TAG, "height: " + height);

Log.i(TAG, "measuredWidth: " + measuredWidth);
Log.i(TAG, "measuredHeight: " + measuredHeight);
复制代码
# 输出结果

width: 0
height: 0
measuredWidth: 0
measuredHeight: 0
java 复制代码
// 使用 View.post 方法处理后

ImageView ivTest = findViewById(R.id.iv_test);

ivTest.post(() -> {
    int width = ivTest.getWidth();
    int height = ivTest.getHeight();

    int measuredWidth = ivTest.getMeasuredWidth();
    int measuredHeight = ivTest.getMeasuredHeight();

    Log.i(TAG, "width: " + width);
    Log.i(TAG, "height: " + height);

    Log.i(TAG, "measuredWidth: " + measuredWidth);
    Log.i(TAG, "measuredHeight: " + measuredHeight);
});
复制代码
# 输出结果

width: 200
height: 200
measuredWidth: 200
measuredHeight: 200
  1. 相对位置相关方法:getLeft、getRight、getTop、getBottom、getX、getY
java 复制代码
ImageView ivTest = findViewById(R.id.iv_test);

int left = ivTest.getLeft();
int right = ivTest.getRight();
int top = ivTest.getTop();
int bottom = ivTest.getBottom();

float x = ivTest.getX();
float y = ivTest.getY();

Log.i(TAG, "left: " + left);
Log.i(TAG, "right: " + right);
Log.i(TAG, "top: " + top);
Log.i(TAG, "bottom: " + bottom);

Log.i(TAG, "x: " + x);
Log.i(TAG, "y: " + y);
复制代码
# 输出结果

left: 0
right: 0
top: 0
bottom: 0
x: 0.0
y: 0.0
java 复制代码
// 使用 View.post 方法处理后

ImageView ivTest = findViewById(R.id.iv_test);

ivTest.post(() -> {
    int left = ivTest.getLeft();
    int right = ivTest.getRight();
    int top = ivTest.getTop();
    int bottom = ivTest.getBottom();

    float x = ivTest.getX();
    float y = ivTest.getY();

    Log.i(TAG, "left: " + left);
    Log.i(TAG, "right: " + right);
    Log.i(TAG, "top: " + top);
    Log.i(TAG, "bottom: " + bottom);

    Log.i(TAG, "x: " + x);
    Log.i(TAG, "y: " + y);
});
复制代码
# 输出结果

left: 0
right: 200
top: 161
bottom: 361
x: 0.0
y: 161.0
  1. 绝对位置相关方法:getLocationOnScreen、getLocationInWindow、getGlobalVisibleRect
java 复制代码
ImageView ivTest = findViewById(R.id.iv_test);

int[] locationOnScreen = new int[2];
ivTest.getLocationOnScreen(locationOnScreen);

int[] locationInWindow = new int[2];
ivTest.getLocationInWindow(locationInWindow);

Rect rect = new Rect();
ivTest.getGlobalVisibleRect(rect);

Log.i(TAG, "locationOnScreen: " + Arrays.toString(locationOnScreen));
Log.i(TAG, "locationInWindow: " + Arrays.toString(locationInWindow));
Log.i(TAG, "rect: " + rect);
复制代码
# 输出结果

locationOnScreen: [0, 0]
locationInWindow: [0, 0]
rect: Rect(0, 0 - 0, 0)
java 复制代码
// 使用 View.post 方法处理后

ImageView ivTest = findViewById(R.id.iv_test);

ivTest.post(() -> {
    int[] locationOnScreen = new int[2];
    ivTest.getLocationOnScreen(locationOnScreen);

    int[] locationInWindow = new int[2];
    ivTest.getLocationInWindow(locationInWindow);

    Rect rect = new Rect();
    ivTest.getGlobalVisibleRect(rect);

    Log.i(TAG, "locationOnScreen: " + Arrays.toString(locationOnScreen));
    Log.i(TAG, "locationInWindow: " + Arrays.toString(locationInWindow));
    Log.i(TAG, "rect: " + rect);
});
复制代码
# 输出结果

locationOnScreen: [0, 161]
locationInWindow: [0, 161]
rect: Rect(0, 161 - 200, 361)
相关推荐
SamDeepThinking1 分钟前
从源码到代码:MyBatis-Flex 与 MyBatis-Plus 的逐项对比
java·后端·程序员
雨白31 分钟前
指针与数组的核心机制
android
她的男孩3 小时前
Spring Boot 接 Flowable 工作流:用 3 个注解搭一个请假审批流程
java·后端·架构
荣码5 小时前
LLM结构化输出:让AI返回JSON而不是废话,我踩了4个坑
java·python
黄林晴5 小时前
Room 3.0 正式发布!包名彻底重构,KMP 成为核心主线
android·android jetpack
三少爷的鞋6 小时前
Kotlin 协程环境下的 DCL 懒加载:别把线程时代的经验直接搬过来
android
plainGeekDev6 小时前
Gson → kotlinx.serialization
android·java·kotlin
小bo波15 小时前
Java Swing 图形用户界面实验 —— 从算术练习到游戏开发的完整实践
java·课程设计·gui·游戏开发·扫雷·swing