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)
相关推荐
limuyang22 小时前
PDF Viewer KMP(基于 chrome 的 PDFium 内核)
android·kotlin
学长毕业设计3 小时前
基于SpringBoot的公益基金管理系统(源码+文档+讲解视频)
java·spring boot·后端
东小西4 小时前
【SAA实战】第 3 篇 · 工具调用全攻略:把业务能力交给 Agent 自己调度
java·后端·spring
东小西4 小时前
【SAA实战】第 4 篇 · Agent 短期记忆:saver 让 Agent 跨轮记得住(threadId 隔离)
java·后端·spring
许彰午4 小时前
22-DataCenter报文序列化
java·低代码·架构·状态模式
2601_962065254 小时前
[MySQL] SQL优化之性能分析
java·sql·mysql
小范同学_4 小时前
JDK1.7 与 JDK1.8 HashMap 底层原理对比 + 数组并发扩容死循环详解
java·开发语言
予昊5 小时前
从零实现“在线五子棋对战“:WebSocket 实时通信 + 段位匹配
java·开发语言·网络·websocket
2601_962203515 小时前
【SpringAI入门】初识SpringAI
java
weixin_461408586 小时前
Mybatis-flex小记
java·开发语言·mybatis