Welcome to Ray's Blog

Stay Hungry Stay Foolish - Steve Jobs

0%

Android View的位置获取笔记


概述

获取 View 的位置信息

  • mLeft = getLeft(): view 左上角横坐标相对于父容器左边框的距离;
  • mRight = getRight(): View 右下角横坐标相对于父容器左边框的距离;
  • mTop = getTop(): View 左上角纵坐标相对于父容器上边框的距离;
  • mBottom = getBottom():View 右下角纵坐标相对于父容器上边框的距离;
  • getTranslationX():View 左上角横坐标相对于mLeft的偏移量;
  • getTranslationY(): View 左上角纵坐标相对于mTop的偏移量;
  • getX()=mLeft+getTranslationX():平移后(mLeft 不变),View 左上角横坐标相对于父容器左边框的距离;(TranslationY 默认为 0);
  • getY=mTop+getTranslationY():平移后(mTop 不变),View 左上角纵坐标相对于父容器上边框的距离;(TranslationY 默认为 0);
  • event.getX():获取当前点击事件相对于 View 本身的横坐标;
  • event.getY():获取当前点击事件相当于 View 本身的纵坐标;
  • event.getRawX():获取当前点击事件在屏幕上的横坐标;
  • event.getRawY(): 获取当前点击事件在屏幕上的纵坐标;

获取 View 宽高的时机

当 Activity 创建时,需要获取某个 View 的宽高,然后进行相应的操作,但是因为 View 的绘制工作还未完成,所以往往在 onCreate、onStart 方法中得到 view 的宽高值为 0。

重写onWindowFocusChanged方法

重写 Activity 中的onWindowFocusChanged,当 Activity 获取到焦点的时候 View 已经绘制完成,也能获取到 view 的准确宽高了。注意该方法可能会被调用多次,只有hasFocus为 true 的时候才能够调用获取 view 宽高的方法。

1
2
3
4
5
6
7
8
9
10
11
/**
* 表示界面的View都绘制完成,可以获取到View的宽和高了
* 注意该方法可能会调用多次
* @param hasFocus
*/
@Override public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
Toast.makeText(this, "可以获取到View的宽和高了", Toast.LENGTH_SHORT).show();
}
}

使用ViewTreeObserver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 获取View的宽高
* @param view
*/
public void getViewSize(final View view) {
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override public boolean onPreDraw() {
int height = view.getMeasuredHeight();
int witdh = view.getMeasuredWidth();
return true; //?? Return true to proceed with the current drawing pass, or false to cancel.
}
});
}

使用viewTreeObserver.addOnGlobalLayoutListener

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 获取View的宽和高
* 要求:SDK大于16 JELLY_BEAN
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) public void getViewSize(final View view) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) { //SDK大于16
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override public void onGlobalLayout() {
/**
* Callback method to be invoked when the global layout state or the visibility of views
* within the view tree changes
*/
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int height = view.getMeasuredHeight();
int witdh = view.getMeasuredWidth();
}
});
}
}

使用View.post(new Runable())

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 获取View的宽和高
* @param view
*/
public void getViewSize(final View view){
view.post(new Runnable() {
@Override public void run() {
int height = view.getMeasuredHeight();
int width = view.getMeasuredWidth();
}
});
}