使用新Android 4.4 KitKat API中的半透明状态和导航栏时,最初将fitsSystemWindows="true"
和clipToPadding="false"
设置为ListView
。 fitsSystemWindows="true"
将列表保留在操作栏下方导航栏上方,clipToPadding="false"
允许列表在透明导航栏下滚动,并使列表中的最后一项向上滚动到足以通过导航杆
但是,当您通过Fragment
将内容替换为另一个FragmentTransaction
时,fitsSystemWindows
的效果会消失,并且片段会位于操作栏和导航栏下。
我在这里有一个演示源代码的代码库以及一个可下载的APK作为示例:https://github.com/afollestad/kitkat-transparency-demo。要查看我正在谈论的内容,请从运行KitKat的设备中打开演示应用程序,点击列表中的项目(这将打开另一个活动),然后点击打开的新活动中的项目。替换内容的片段位于操作栏下,并且clipToPadding无法正常工作(当您向下滚动时,导航栏将覆盖列表中的最后一项)。
有什么想法吗?需要澄清吗?我发布了为我的雇主开发的个人应用程序的前后屏幕截图。
答案 0 :(得分:12)
首先,我在ViewParent
上看到了方法requestFitSystemWindows()
,我尝试在片段onActivityCreated()
中调用它(在片段附加到视图层次结构之后)但是可悲的是,它没有任何效果。我想看一个如何使用该方法的具体例子。
然后我找到了一个简洁的解决方法:我创建了一个自定义FitsSystemWindowsFrameLayout
,我在布局中用作片段容器,作为经典{{1}的替代品}。它的作用是在系统调用FrameLayout
时记住窗口插入,然后在添加/附加片段后再将调用再次传播到其子布局(片段布局)。
这里是完整的代码:
fitSystemWindows()
我认为这比试图通过访问可能随时间变化的隐藏系统属性来确定UI元素大小的黑客更加简单和强大,然后手动将填充应用于元素。
答案 1 :(得分:9)
我通过使用库来解决了这个问题我设置了半透明状态栏的颜色。
SystemBarTint的SystemBarConfig
类(如此处所见https://github.com/jgilfelt/SystemBarTint#systembarconfig)允许您获取插件,我将其设置为每个片段中列表的填充,以及使用clipToPadding="false"
on清单。
我详细了解了我在这篇文章中所做的工作:http://mindofaandroiddev.wordpress.com/2013/12/28/making-the-status-bar-and-navigation-bar-transparent-with-a-listview-on-android-4-4-kitkat/
答案 2 :(得分:8)
好的,所以这非常奇怪。我刚刚遇到了同样的问题,除了我的涉及软键盘。它最初有效但如果我添加片段事务,android:fitsSystemWindows="true"
不再有效。我在这里尝试了所有的解决方案,但没有一个能为我工作。
这是我的问题:
而不是重新调整我的观点,它推动了我的观点,这就是问题所在。
但是,我很幸运,不小心偶然发现了一个对我有用的答案!
所以这是:
首先,我的应用主题是:Theme.AppCompat.Light.NoActionBar(如果这是相关的,也许是,android很奇怪)。
Maurycy在这里指出了一些非常有趣的东西,所以我想测试他说的是不是真的。他说的内容在我的情况下也是如此......除非你在app的Android清单中将此属性添加到你的活动中:
添加后:
android:windowSoftInputMode="adjustResize"
到您的活动,片段事务后不再忽略android:fitsSystemWindows="true"
!
但是,我更喜欢你在片段的根布局上调用android:fitsSystemWindows="true"
。如果您有EditText或ListView,最容易出现此问题的地方之一就是。如果你像我一样陷入困境,请在根布局的子项中设置android:fitsSystemWindows="true"
,如下所示:
是的,此解决方案适用于所有棒棒糖和棒棒糖前设备。
以下是证据:
重新调整尺寸,而不是向上推动布局。 所以希望,我帮助了和我在同一条船上的人。
非常感谢你们!
答案 3 :(得分:5)
让一些人遇到这个问题。
使用fitSystemWindows方法完成大量工作的关键信息:
此功能在层次结构中的遍历是深度优先的。相同 内容insets对象沿层次结构向下传播,因此任何更改 所有以下观点(包括潜在的观点)都会看到它 层次结构中的那些,因为这是深度优先遍历)。 返回true的第一个视图将中止整个遍历。
因此,如果您有任何其他片段的内容视图,其中fitsSystemWindows设置为true,则可能会忽略该标志。如果可能的话,我会考虑让你的片段容器包含fitsSystemWindows标志。否则手动添加填充。
答案 4 :(得分:2)
我也一直在苦苦挣扎。 我在这里看到了所有的回复。不幸的是,他们都没有在100%的时间内解决我的问题。 SystemBarConfig始终无法正常工作,因为它无法检测某些设备上的栏。 我看了一下源代码,找到了在窗口中存储插图的位置。
Rect insets = new Rect();
Window window = getActivity().getWindow();
try {
Class clazz = Class.forName("com.android.internal.policy.impl.PhoneWindow");
Field field = clazz.getDeclaredField("mDecor");
field.setAccessible(true);
Object decorView = field.get(window);
Field insetsField = decorView.getClass().getDeclaredField("mFrameOffsets");
insetsField.setAccessible(true);
insets = (Rect) insetsField.get(decorView);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
这是如何获得它们的。 显然在Android L中,有一个很好的方法可以获得这些插入,但与此同时这可能是一个很好的解决方案。
答案 5 :(得分:0)
我已在4.4
中解决了这个问题if(test){
Log.d(TAG, "fit true ");
relativeLayout.setFitsSystemWindows(true);
relativeLayout.requestFitSystemWindows();
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}else {
Log.d(TAG, "fit false");
relativeLayout.setFitsSystemWindows(false);
relativeLayout.requestFitSystemWindows();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}