getLocationOnScreen() vs getLocationInWindow()

2022-08-31 13:45:48

在这两种方法的上下文中,屏幕和视图有什么区别?

我有一个按钮,我想得到它中心的x坐标。

我想这就足够了:

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

但是,如果我使用,它会有什么区别

getLocationOnScreen()或?getLocationInWindow()

(当然,将按钮宽度的一半添加到此)


答案 1

我不认为这个答案是正确的。如果我创建一个新项目,并通过添加以下代码段仅编辑 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);
}

我会看到打印到控制台。这是使用运行4.3的Nexus 7。我使用运行Android版本的模拟器获得类似的结果,最早可追溯到2.2。108 108

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

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

如果单步执行这两种方法的源,您将看到视图的视图层次结构向上遍历到 RootViewImpl,对视图坐标求和并减去父滚动偏移量。在我上面描述的情况下,ViewRootImpl从WindowSession获取状态栏高度,并通过fitSystemWindows将其传递到ActionBarOverlayLayout,后者将此值添加到操作栏高度。然后,ActionBarOverlayLayout 获取此求和值,并将其作为边距应用于其内容视图(即布局的父级)。getLocationInWindow

因此,您的内容布局低于状态栏,不是由于窗口从比状态栏更低的 y 坐标开始,而是由于将边距应用于活动的内容视图。

如果你窥视源代码,你会看到它只是调用,然后添加窗口的左侧和顶部坐标(这些坐标也由ViewRootImpl传递给View,后者从WindowSession中获取它们)。在正常情况下,这些值都将为零。在某些情况下,这些值可能不为零,例如,放置在屏幕中间的对话窗口。getLocationOnScreengetLocationInWindow


因此,总而言之:正常活动的窗口会填满整个屏幕,甚至是状态栏和装饰品下方的空间。所讨论的两种方法将返回相同的 x 和 y 坐标。只有在特殊情况下,例如窗口实际偏移的对话框,这两个值才会有所不同。


答案 2

getLocationOnScreen()将根据手机屏幕获取位置。
将根据活动窗口获取位置。getLocationInWindow()

对于正常活动(非全屏活动),与手机屏幕和活动窗口的关系如下所示:

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

对于坐标,两种方法的值通常是相同的。
对于坐标,这些值与状态栏的高度有差异。xy


推荐