我有一个Android应用,其主题具有以下设置:
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
层次结构中的顶部视图将覆盖onApplyWindowsInsets()
。该实现只记录它传递的WindowInsets
,然后调用超类方法,记录结果并返回它-无需进行任何修改。日志还显示,超类方法不会修改插图。
现在我得到一个奇怪的顶部插图,看起来总是比我期望的要高出56-72 dp。
Platform DPI Layout Inset Bar Difference
Android x86_64 8.1 MDPI Landscape 88 px/dp 24 px/dp 64 px/dp
Landscape, split 80 px/dp 24 px/dp 56 px/dp
Anbox MDPI Window 64 px/dp None 64 px/dp
LineageOS 15.1 XXHDPI Portrait 240 px/80 dp 72 px/24 dp 168 px/56 dp
Portrait, split/top 216 px/73 dp 72 px/24 dp 144 px/48 dp
Portrait, split/bottom 144 px/48 dp None 144 px/48 dp
SDK Emulator (6.0) HDPI Portrait 120 px/80 dp 36 px/24 dp 84 px/56 dp
注意:在横向模式下,有两个连续的onApplyWindowInsets()
调用,此处仅报告最后一个。
该视图实际上并没有超出可见范围的顶部:如果我在视图顶部绘制一个24像素的区域,它会出现在可见区域的顶部(即,如果有的话,在状态栏下方)一个),永远不会在屏幕外显示。
如果我相信这些插入值和偏移量所指示的像素数,以使其远离系统条,那么我将在视图顶部保留一个空白。
据我所知,左/右/底值似乎还可以。
我该如何纠正?我在俯视什么吗?
答案 0 :(得分:0)
由于我仍然无法解释所报告的值,因此我认为这要么是错误,要么是文档记载不充分的功能,尽管如此,它在许多(如果不是全部)Android版本中都存在。
幸运的是,至少在API 23+上,还有另一种获取窗口插图的方法,即调用View#getWindow().getRootView().getRootWindowInsets()
。这似乎具有some bugs of its own,即报告导航栏的插入不正确,但是将两个结果合并对我来说是有用的。
onApplyWindowsInsets()
的插图,仅丢弃最上面的一个。onSizeChanged()
,并在其中调用View#getRootWindowInsets()
以获取顶部插图(忽略其他插图)。合并的值对我有用。
不幸的是,这不适用于未实现View#getRootWindowInsets()
的API 20-22。在这里,您将需要做一些猜测。幸运的是,这很容易,因为这些API尚未实现分屏显示-顶部插图将是状态栏的高度,除非您明确要求将其隐藏(在这种情况下为0)。如果状态栏可见,则可以按以下方式确定其高度:
Resources resources = view.getResources();
int shid = resources.getIdentifier("status_bar_height", "dimen", "android");
padding_top = (shid > 0) ? resources.getDimensionPixelSize(shid) : 0;