文章目录
Android坐标系
概述
Android有两种坐标系,分别为Android坐标系和视图坐标系。
屏幕坐标系
在Android中,将屏幕的左上角作为Android坐标系的原点,原点向右为X轴正方向,原点向下为Y轴正方向。
View坐标系
View获取自身宽高
方法 | 说明 |
---|---|
getHeight() | 获取View自身高度 |
getWidth() | 获取View自身宽度 |
View自身坐标
方法 | 说明 |
---|---|
getTop() | 获取View顶边到其父布局顶边的距离 |
getLeft() | 获取View左边到其父布局左边的距离 |
getRight() | 获取View右边到其父布局左边的距离 |
getBottom() | 获取View底边到其父布局顶边的距离 |
MotionEvent方法
触摸点的坐标方法
方法 | 说明 |
---|---|
getX() | 触摸点距离控件左边的距离 |
getY() | 触摸点距离控件顶边的距离 |
getRawX() | 触摸点距离屏幕左边的距离 |
getRawY() | 触摸点距离屏幕顶边的距离 |
准确获取View的坐标宽高
有时我们需要获取View
的宽高,但是即使我们在onResume
中获取,有时候也是不准确的。这是因为View的measure流程和Activity的生命周期方法不是同步的,因此在onCreate、onStart、onResume无法保证获取正确的信息。
那么到底该如何获取View
准确的宽高呢?
Activity/View#onWindowFocusChanged()
View已经完成初始化操作,当Activity的窗口得到焦点和失去焦点均会被调用。
此方法会被调用多次。
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
int top = imageView.getTop();
int left = imageView.getLeft();
int width = imageView.getMeasuredWidth();
Log.e("TAG", "onWindowFocusChanged: " + top + "-" + left + "-" + width);
}
}
View#post()
添加到消息队列中,执行该任务时View已经完成初始化操作。
imageView.post(new Runnable() {
@Override
public void run() {
int top = imageView.getTop();
int left = imageView.getLeft();
int width = imageView.getMeasuredWidth();
Log.e("TAG", "post: " + top + "-" + left + "-" + width);
}
});
ViewTreeObserver#addOnGlobalLayoutListener()
监听View树状态变化。
imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int top = imageView.getTop();
int left = imageView.getLeft();
int width = imageView.getMeasuredWidth();
Log.e("TAG", "getViewTreeObserver(): " + top + "-" + left + "-" + width);
}
});