gpt4 book ai didi

java - getLocationOnScreen() 与 getLocationInWindow()

转载 作者:IT老高 更新时间:2023-10-28 13:20:40 28 4
gpt4 key购买 nike

这两种方法的上下文中screen和view有什么区别?

我有一个按钮,我想获取其中心的 x 坐标。

我想这就够了:

public int getButtonXPosition() {
return (button.getLeft()+button.getRight())/2;
}

但是,如果我使用它会有什么不同

getLocationOnScreen()getLocationInWindow() ?

(当然是按钮宽度的一半)

最佳答案

我不认为 this answer是正确的。如果我创建一个新项目,并通过添加以下代码段仅编辑 MainActivity:

public boolean dispatchTouchEvent(MotionEvent ev) {
View contentsView = findViewById(android.R.id.content);

int test1[] = new int[2];
contentsView.getLocationInWindow(test1);

int test2[] = new int[2];
contentsView.getLocationOnScreen(test2);

System.out.println(test1[1] + " " + test2[1]);

return super.dispatchTouchEvent(ev);
}

我会看到打印到控制台108 108。这是使用运行 4.3 的 Nexus 7。使用运行 android 版本的模拟器,我也有类似的结果,可以追溯到 2.2。

普通 Activity 窗口将 FILL_PARENTxFILL_PARENT 作为其 WindowManager.LayoutParams,这导致它们布局为整个屏幕的大小。窗口位于状态栏和其他装饰下方(关于 z 顺序,而不是 y 坐标),所以我相信更准确的图表是:

|--phone screen-----activity window---| 
|--------status bar-------------------|
| |
| |
|-------------------------------------|

如果您逐步了解这两种方法的源代码,您会看到 getLocationInWindow 向上遍历 View 的 View 层次结构,直至 RootViewImpl,将 View 坐标和减去父滚动偏移量。在我上面描述的情况下,ViewRootImpl 从 WindowSession 获取状态栏高度,并通过 fitSystemWindows 向下传递到 ActionBarOverlayLayout,它将这个值添加到操作栏高度。 ActionBarOverlayLayout 然后将这个总和值应用到它的内容 View ,它是你的布局的父级,作为一个边距。

因此,您的内容布局低于状态栏并不是因为窗口从低于状态栏的 y 坐标开始,而是因为您的 Activity 的内容 View 应用了边距。

如果您查看 getLocationOnScreen 源代码,您会看到它只是调用 getLocationInWindow 然后添加窗口的左坐标和上坐标(也通过ViewRootImpl,它从 WindowSession 中获取它们)。在正常情况下,这些值都为零。在某些情况下,这些值可能不为零,例如位于屏幕中间的对话窗口。


所以,总结一下:一个正常 Activity 的窗口会填满整个屏幕,甚至是状态栏和装饰下方的空间。有问题的两种方法将返回相同的 x 和 y 坐标。只有在特殊情况下,例如窗口实际偏移的对话框,这两个值才会不同。

关于java - getLocationOnScreen() 与 getLocationInWindow(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17672891/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com