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
问题原因
-
当一个 Activity 启动时,视图的创建和显示需要经过几个关键阶段:视图创建阶段 -> 测量阶段 -> 布局阶段 -> 绘制阶段
-
在 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 方法中,任何需要等待测量和布局阶段完成后才能确定的信息都无法获取,例如
- 尺寸相关方法: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
- 相对位置相关方法: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
- 绝对位置相关方法: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)