java getLocationOnScreen()与getLocationInWindow()的比较
在这两种方法的上下文中,screen和view之间有什么区别
我有一个按钮,我想得到它中心的x坐标
我想这就足够了:
public int getButtonXPosition() {
return (button.getLeft()+button.getRight())/2;
}
但是,如果我使用
getLocationOnScreen()
还是getLocationInWindow()
(当然,还要加上按钮宽度的一半)
# 1 楼答案
getLocationOnScreen()
将根据手机屏幕获取位置getLocationInWindow()
将根据活动窗口获取位置对于正常活动(非全屏活动),与手机屏幕和活动窗口的关系如下所示:
对于
x
坐标,两种方法的值通常相同对于
y
坐标,这些值与状态栏的高度不同# 2 楼答案
我认为this answer是不对的。如果我创建了一个新项目,并通过添加以下代码片段仅编辑MainActivity:
我将看到打印到控制台
108 108
。这是使用运行4.3的Nexus7。我使用运行早在2.2版本的android的模拟器得到了类似的结果正常活动窗口将使用FILL_PARENTxFILL_Parents作为窗口管理器。LayoutParams,这会导致它们按照整个屏幕的大小进行布局。窗口位于状态栏和其他装饰的下方(相对于z坐标,而不是y坐标),因此我认为更准确的图表应该是:
如果仔细查看这两个方法的源代码,您将看到
getLocationInWindow
沿着视图的视图层次向上遍历到RootViewImpl,将视图坐标和 减去父滚动偏移。在我上面描述的例子中,ViewRootImpl从WindowsSession获取状态栏高度,并通过fitSystemWindows将其传递到ActionBarOverlayLayout,从而将该值添加到actionbar高度。ActionBarOverlayLayout然后将该求和值作为边距应用于其内容视图,该视图是布局的父视图因此,内容的布局低于状态栏,不是因为窗口的y坐标低于状态栏,而是因为活动的内容视图应用了边距
如果你查看
getLocationOnScreen
源代码,你会发现它只会调用getLocationInWindow
,然后添加窗口的左坐标和上坐标(这些坐标也由ViewRootImpl传递给视图,后者从WindowsSession获取它们)。在正常情况下,这些值都将为零。有些情况下,这些值可能是非零的,例如放置在屏幕中间的对话框窗口。因此,总结一下:一个正常活动的窗口占据了整个屏幕,甚至是状态栏和装饰下的空间。这两种方法将返回相同的x和y坐标。只有在特殊情况下,例如窗口实际偏移的对话框,这两个值才会不同
# 3 楼答案
目前公认的答案有点罗嗦。这是一个较短的
getLocationOnScreen()
和getLocationInWindow()
通常返回相同的值。这是因为窗口通常与屏幕大小相同。然而,有时窗口比屏幕小。例如,在Dialog
或自定义系统键盘中因此,如果你知道你想要的坐标总是相对于屏幕的(就像在正常活动中),那么你可以使用
getLocationOnScreen()
。但是,如果视图所在的窗口可能比屏幕小(如对话框或自定义键盘),则使用getLocationInWindow()
相关的
# 4 楼答案
对于^{} ,
x
和y
将返回视图的左上角使用^{} 将是相对于其容器的,而不是整个屏幕。如果根布局小于屏幕(如在对话框中),则这将不同于
getLocationOnScreen()
。在大多数情况下,它们是相同的Java解决方案
要确保视图有机会更新,请在使用
view.post
计算视图的新布局后运行位置请求:~~
科特林溶液
要确保视图有机会更新,请在使用
view.post
计算视图的新布局后运行位置请求:我建议创建一个扩展函数来处理这个问题:
如果您需要可靠性,还可以添加: