在这两种方法的上下文中,屏幕和视图有什么不同?
我有一个按钮,我想要得到它中心的x坐标。
我想这就足够了:
public int getButtonXPosition() {
return (button.getLeft()+button.getRight())/2;
}
但是,如果我使用了
getLocationOnScreen()
还是getLocationInWindow()
?
(当然,再加上按钮宽度的一半)
发布于 2013-11-23 05:11:45
我不认为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。我使用运行早在2.2版本的android版本的仿真器也得到了类似的结果。
正常的活动窗口将使用FILL_PARENTxFILL_PARENT作为其WindowManager.LayoutParams,这将导致它们的布局达到整个屏幕的大小。窗口位于状态栏和其他装饰的下方(关于z顺序,而不是y坐标),因此我认为更准确的图表应该是:
|--phone screen-----activity window---|
|--------status bar-------------------|
| |
| |
|-------------------------------------|
如果您逐句了解这两种方法的源代码,您将看到getLocationInWindow
遍历视图的视图层次结构直到RootViewImpl,计算视图坐标并减去父滚动偏移量。在我上面描述的情况下,ViewRootImpl从WindowSession获取状态栏高度,并通过fitSystemWindows将其向下传递给ActionBarOverlayLayout,这会将该值添加到操作栏高度。然后,ActionBarOverlayLayout将这个相加值作为边距应用于其内容视图,该视图是您的布局的父级。
因此,您的内容布局低于状态栏,不是因为窗口从比状态栏更低的y坐标开始,而是因为将边距应用于您的活动的内容视图。
如果仔细查看getLocationOnScreen
源代码,您会发现它只是调用了getLocationInWindow
,然后添加了窗口的左侧和顶部坐标(这些坐标也由ViewRootImpl传递给视图,后者从WindowSession中获取它们)。在正常情况下,这两个值都是零。在某些情况下,这些值可能是非零的,例如,位于屏幕中间的对话框窗口。
因此,总结一下:一个正常活动的窗口充满了整个屏幕,甚至状态栏和装饰物下面的空间也是如此。这两个方法将返回相同的x和y坐标。只有在特殊情况下,例如窗口实际偏移的对话框,这两个值才会不同。
https://stackoverflow.com/questions/17672891
复制相似问题