我有RelativeLayout
,其大小占据了包含Activity
的所有屏幕区域。也就是说,它会填充除通知栏以外的所有屏幕区域。
我正在使用ActionBarSherlock。 ActionBar使用getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY)
设置为叠加模式。因此,我的RelativeLayout
的高度从通知栏的正下方直到屏幕的底部,并且它所拥有的任何子View
都可能放在ActionBar后面。因此ActionBar肯定在叠加模式下运行。我确认在运行2.2,4.0.x(ICS)和4.1(JB)的设备上就是这种情况。
因为我的应用程序在这个RelativeLayout
中实现了拖放机制,所以我需要知道布局在屏幕上的位置,以便我可以更正getRawY()
返回的绝对屏幕Y触摸值。为实现这一目标,在布局阶段完成后,我一直在mRelativeLayout.getLocationOnScreen()
内调用onWindowFocusChanged()
。
在我的4.0和4.1设备上,对getLocationOnScreen()
的调用产生的Y值与最顶层通知栏的高度(以像素为单位)相匹配。为了确定通知栏和ActionBar组合的高度,我将getLocationOnScreen()
返回的Y值添加到ActionBarSherlock的getHeight()
方法的结果中。
问题是,在2.2设备上进行测试时,getLocationOnScreen()
返回的Y值已经是通知栏高度加上ABS高度。即使ABS设置为叠加模式,也是如此。
关于来自getLocationOnScreen()
的令人难以置信的结果,有几个关于SO的问题;一个here有一个答案让我想放弃getLocationOnScreen()
,而是通过从总屏幕高度减去布局的高度来计算RelativeLayout
的前Y偏移:
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(dm);
int mRelativeLayoutYOffs = dm.heightPixels - mRelativeLayout.getMeasuredHeight();
我发现这个结果的奇怪之处在于它似乎给了我与getLocationOnScreen()
相同的不一致性。 2.2上发生的情况是.getMeasuredHeight()
上对RelativeLayout
的调用实际上似乎是给出了一个高度值,该高度值从RelativeLayout
的实际高度减去了ActionBar高度,即使将ABS设置为叠加,我已经在视觉上确认它绝对处于叠加模式。
我现在能想到的最好的策略是根据操作系统版本区别对待getLocationOnScreen()
的结果。如果它是2.2,那么我知道它包括ABS高度。如果4.0以上,则不会。 2.2和4.0之间的任何东西,我还不确定。也许人们可以帮助填补这些细节。也许差异是在本机支持ActionBar的操作系统版本中引入的?如果它是可预测的并且很好地定义了行为是什么,那么希望这将是一个安全的策略。
如果不这样做,是否有其他方法可以确定RelativeLayout
的左上角和左上角位置以纠正绝对屏幕触摸值?
答案 0 :(得分:5)
问题是因为我不应该使用getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY)
。 Intead,我的自定义样式(继承自父ActionBarSherlock主题)需要包含:
<item name="android:windowActionBarOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
此外,我说在2.2上ABS正在以叠加模式工作时说错了 - 事实上,事实并非如此。现在我正在使用上面的样式项,它现在在2.2中以叠加模式工作。
.getLocationOnScreen()
现在正确返回Y值,该值仅代表我的2.2,4.0和4.1设备上的通知栏高度。