getGlobalVisibleRect、getLocalVisibleRect、getLocationInWindow、getLocationOnScreen

测试布局
在这里插入图片描述

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/linearlayout_test"
        android:layout_marginLeft="50px"
        android:layout_marginTop="50px"
        android:layout_width="200px"
        android:layout_height="200px"
        android:background="@color/colorPrimary"
        android:orientation="vertical"/>

</LinearLayout>

getGlobalVisibleRect()

这个方法会返回一个 View 是否可见的 boolean 值。以屏幕左上角为参考系,判断view是否有一部分仍然在屏幕中(没有被父View遮挡),则会返回true。反之,如果它全部被父View遮挡住或者本身就是不可见的,则会返回false

同时还会将该 View 的可见区域 left,top,right,bottom 值保存在一个rect对象中
在这里插入图片描述
该Rect是基于总整个屏幕的。若是普通activity,则 Rect 的 top 为可见的状态栏高度+可见的标题栏高度+ Rect 左上角到标题栏底部的距离

若是对话框式的 activity,则 y 坐标为 Rect 的 top 为可见的标题栏高度 + Rect 左上角到标题栏底部的距离,此时是无视状态栏的有无的

Rect rect = new Rect();
boolean b = linearLayout.getGlobalVisibleRect(rect);
if(b){
	Log.d("getGlobalVisibleRect",""+rect);
}

在这里插入图片描述

getLocalVisibleRect()

这个方法跟getGlobalVisibleRect用法相同,只不过是以 view 自身的左上角为参考系
在这里插入图片描述

以上方法在 OnCreate 方法中调用,都会返回 0,这是因为 View 还未加载完毕

getLocationInWindow()

一个控件在其父窗口中的坐标位置,获取在当前窗口内的绝对坐标
getLocationInWindow 是以B为原点的C的坐标
在这里插入图片描述
若是普通activity,则 y 坐标为可见的状态栏高度 + 可见的标题栏高度 + view左上角到标题栏底部的距离(可见的意思是:在隐藏了状态栏/标题栏的情况下,它们的高度以0计算)

若是对话框式的 activity,则 y 坐标为可见的标题栏高度 + view 到标题栏底部的距离,此时是无视状态栏的有无的

int[] location = new int[2];
linearLayout.getLocationInWindow(location);
int x = location[0];
int y = location[1];
Log.d("getLocationInWindow", "x:" + x + ",y:" + y);

在这里插入图片描述

getLocationOnScreen()

一个控件在其整个屏幕上的坐标位置,获取在整个屏幕内的绝对坐标,注意这个值是要从屏幕顶端算起,也就是包括了通知栏的高度

getLocationOnScreen以A为原点的C的坐标

在这里插入图片描述
注意
当view没有绑定到window时,返回在window里的坐标是没有意义的,以上4个方法如果在Activity的OnCreate()事件输出那些参数,是全为0,要等UI控件都加载完了才能获取到这些。所以可以在以下函数中调用这些方法

	@Override
    public void onWindowFocusChanged(boolean hasFocus) {
    ......
    }
<think>好的,我现在要帮用户解决关于Android中getLocationOnScreen方法的问题,用户需要教程或常见问题。首先,我需要回忆一下这个方法的具体用法和相关知识。 记得getLocationOnScreen(int[] outLocation)是用来获取视图在屏幕上的坐标的,坐标相对于整个屏幕。那这个方法返回的outLocation数组,第一个元素是x坐标,第二个是y坐标。用户可能想知道怎么正确使用这个方法,或者遇到坐标不对的情况怎么办。 接下来,我需要整理使用步骤。首先,用户需要获取目标视图的实例,比如通过findViewById。然后创建一个int数组,通常是长度为2,调用view.getLocationOnScreen(location)。之后就能读取数组中的坐标了。可能需要提醒用户注意调用时机,比如在视图布局完成之后才能获取正确的坐标,否则可能得到0。 然后常见问题部分,用户可能会遇到坐标始终为0,这时候应该检查是否在onCreate里调用了,这时候视图还没渲染。应该建议在onWindowFocusChanged或者ViewTreeObserver的OnGlobalLayoutListener里调用。另外,可能坐标计算不准确,比如视图有父布局的偏移,或者有状态栏、导航栏的影响,这时候可能需要考虑屏幕的装饰区域。 还有可能用户想计算相对位置,比如相对于另一个视图的位置,这时候可以用两个视图的坐标相减。另外,PopupWindow的定位可能会用到这个方法,比如引用中的例子,需要获取父视图的位置来动态计算弹出位置。 还要注意屏幕旋转的情况,坐标可能会变,所以需要重新获取。另外,多Fragment的情况下,控件可能在屏幕外,这时候用这个方法判断是否可见,如引用1提到的,判断x坐标是否在屏幕宽度范围内。 可能需要提到和getLocationInWindow的区别,后者是相对于窗口的坐标,如果有状态栏等情况,这两个方法的结果会有差异。比如全屏模式下,两者可能相同,但非全屏时可能不同。 最后,给出示例代码,比如在按钮点击时获取坐标,或者在布局完成后使用ViewTreeObserver来确保正确获取。同时,结合用户的引用内容,比如引用2提到PopupWindow的位置计算,引用1提到多Fragment中的可见性判断,引用4可能涉及测试时的使用,但用户的问题可能更多在开发中的使用。 需要确保回答结构清晰,分步骤说明使用方法,常见问题,注意事项,示例代码,以及相关问题。可能用户的实际问题包括坐标不准、时机不对、相对位置计算等,需要覆盖这些点。 检查是否有遗漏,比如坐标是否包含状态栏高度,或者不同API版本的表现是否一致。可能需要提醒用户进行实际测试,或者使用工具查看布局边界。同时,确保LaTeX格式正确,行内公式用$包围,独立公式用$$,但在这个回答中可能用不上太多数学公式,主要关注代码和文字描述。 最后生成相关问题,比如和getLocationInWindow的区别,如何动态计算位置,或者如何处理多屏幕适配的情况。确保问题相关且有帮助。</think>### Android getLocationOnScreen 方法使用教程 #### 一、方法作用与语法 `View.getLocationOnScreen(int[] outLocation)` 用于获取视图左上角在屏幕坐标系中的绝对位置,返回的坐标值包含状态栏高度。语法格式如下: ```java int[] location = new int[2]; view.getLocationOnScreen(location); // location[0]为X坐标,location[1]为Y坐标 ``` #### 二、使用步骤 1. **获取视图实例**:通过 `findViewById` 获取目标视图的引用。 2. **创建坐标数组**:声明长度为2的整型数组。 3. **调用方法**:在视图完成布局后调用方法(如 `onWindowFocusChanged` 或 `ViewTreeObserver` 回调中)。 4. **处理坐标数据**:通过数组索引获取具体坐标值。 #### 三、典型应用场景 1. **动态计算弹窗位置** 通过父视图的屏幕坐标计算弹窗偏移量(如引用[2]所述): ```java int[] parentLocation = new int[2]; parentView.getLocationOnScreen(parentLocation); popupWindow.showAtLocation(parentView, Gravity.START|Gravity.TOP, parentLocation[0] + offsetX, parentLocation[1] + offsetY); ``` 2. **判断控件可见性** 结合屏幕尺寸验证控件是否在可视范围内(如引用[1]所述): ```java DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int screenWidth = metrics.widthPixels; int[] location = new int[2]; view.getLocationOnScreen(location); boolean isVisible = (location[0] >= 0 && location[0] <= screenWidth); ``` #### 四、常见问题与解决方案 | 问题现象 | 原因分析 | 解决方案 | |---------|----------|----------| | 始终返回[0,0] | 过早调用(如onCreate阶段) | 在`onWindowFocusChanged`或布局监听器中调用 | | Y坐标包含状态栏高度 | 系统坐标系设计特性 | 手动减去状态栏高度:`location[1] - statusBarHeight` | | 旋转屏幕后坐标错误 | 未重新获取坐标 | 添加屏幕方向监听并刷新坐标 | #### 五、代码示例 ```java view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int[] location = new int[2]; view.getLocationOnScreen(location); Log.d("Coordinates", "X: " + location[0] + ", Y: " + location[1]); view.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); ``` #### 六、进阶技巧 1. **坐标系转换** 使用 `getLocationInWindow()` 获取相对于应用窗口的坐标(不包含系统装饰)。 2. **多屏适配** 通过 `Display.getRealMetrics()` 获取实际屏幕尺寸处理折叠屏场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值