昨天读一个Android sample代码的时候,发现获取屏幕位置的代码使用了 public boolean getGlobalVisibleRect(Rect r, Point globalOffset) 这个API,不是很理解,就动手调试计算了一下,记录一下心得。
先看下源码注释:
/**
* If some part of this view is not clipped by any of its parents, then
* return that area in r in global (root) coordinates. To convert r to local
* coordinates (without taking possible View rotations into account), offset
* it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)).
* If the view is completely clipped or translated out, return false.
*
* @param r If true is returned, r holds the global coordinates of the
* visible portion of this view.
* @param globalOffset If true is returned, globalOffset holds the dx,dy
* between this view and its root. globalOffet may be null.
* @return true if r is non-empty (i.e. part of the view is visible at the
* root level.
*/
public boolean getGlobalVisibleRect(Rect r, Point globalOffset)
该函数的重载版本:
public final boolean getGlobalVisibleRect(Rect r) {
return getGlobalVisibleRect(r, null);
}
第二个参数 Point globalOffset 用于将global坐标转换成local坐标。这里的local坐标,是相对于内容区的坐标,也就是除了状态栏和action bar和虚拟按键的区域。
举个例子:
获得global坐标:
thumbView.getGlobalVisibleRect(startBounds);
findViewById(R.id.container).getGlobalVisibleRect(finalBounds, globalOffset);
将global坐标减去偏移量,得到local坐标。也就是,将屏幕坐标转换成内容区坐标。 startBounds.offset(-globalOffset.x, -globalOffset.y); finalBounds.offset(-globalOffset.x, -globalOffset.y);
以第一个缩略图为例,getGlobalVisibleRect 获得矩形边界startBounds (32,248,232,398), 偏移globalOffset (0,146)
矩形是左上右下四个点的坐标, 也可以看做是左上坐标和右下坐标。减去偏移得到 (0,102,232,252)
刚好和上图标注吻合。