Android 4.4 - 半透明状态/导航栏 - fitsSystemWindows/clipToPadding无法通过片段事务处理

afo*_*tad 27 android transparent fragment android-4.4-kitkat

当使用新的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无法正常工作(当您向下滚动时,导航栏将覆盖列表中的最后一项).

有任何想法吗?需要澄清吗?我发布了为我的雇主开发的个人应用程序的前后屏幕截图.

一 二

Bla*_*der 12

我昨天也遇到了同样的问题.经过深思熟虑之后,我找到了解决这个问题的优雅方案.

首先,我看到的方法requestFitSystemWindows()ViewParent,我试图把它叫这个片断onActivityCreated()(这个片段连接后视图层次),但遗憾的是它没有任何效果.我想看一个如何使用该方法的具体示例.

然后我找到了一个简洁的解决方法:我创建了一个自定义FitsSystemWindowsFrameLayout,我在布局中用作片段容器,作为经典的替代品FrameLayout.它的作用是fitSystemWindows()在系统调用时记住窗口插入,然后在添加/附加片段后再将调用再次传播到其子布局(片段布局).

这是完整的代码:

public class FitsSystemWindowsFrameLayout extends FrameLayout {

    private Rect windowInsets = new Rect();
    private Rect tempInsets = new Rect();

    public FitsSystemWindowsFrameLayout(Context context) {
        super(context);
    }

    public FitsSystemWindowsFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FitsSystemWindowsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected boolean fitSystemWindows(Rect insets) {
        windowInsets.set(insets);
        super.fitSystemWindows(insets);
        return false;
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        super.addView(child, index, params);
        tempInsets.set(windowInsets);
        super.fitSystemWindows(tempInsets);
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为这比试图通过访问可能随时间变化的隐藏系统属性来确定UI元素大小的黑客更简单和更健壮,然后手动将填充应用于元素.


afo*_*tad 9

我通过使用库来解决问题我使用了设置半透明状态栏的颜色.

SystemBarConfig类SystemBarTint的(如这里看到https://github.com/jgilfelt/SystemBarTint#systembarconfig)让你得到的插图,我在每一个片段设置为填充到列表中,使用的一起clipToPadding="false"就行了.

我详细介绍了我在这篇文章中所做的工作:http://mindofaandroiddev.wordpress.com/2013/12/28/making-the-status-bar-and-navigation-bar-transparent-with-a-listview -酮的Android-4-4-奇巧/


小智 8

好的,所以这非常奇怪.我刚刚遇到了同样的问题,除了我的软键盘.它最初有效但如果我添加片段事务,则android:fitsSystemWindows="true"不再有效.我在这里尝试了所有的解决方案,它们都没有为我工作.

这是我的问题: 在此输入图像描述

它没有重新调整我的观点,而是推动了我的观点,这就是问题所在.

然而,我很幸运,不小心偶然发现了一个对我有用的答案!

所以这里是:

首先,我的应用主题是:Theme.AppCompat.Light.NoActionBar(如果这是相关的,也许是,android很奇怪).

Maurycy在这里指出了一些非常有趣的东西,所以我想测试他说的是不是真的.他说的话在我的情况下也是如此......除非你在app的android清单中将此属性添加到你的活动中:

在此输入图像描述

添加后:

android:windowSoftInputMode="adjustResize" 
Run Code Online (Sandbox Code Playgroud)

对于你的活动,android:fitsSystemWindows="true"片段交易后不再被忽略!

但是,我更喜欢你android:fitsSystemWindows="true"不要在片段的根布局上调用.如果您有EditText或ListView,最容易出现此问题的地方之一就是.如果你像我一样陷入困境,请设置android:fitsSystemWindows="true"根布局的子项,如下所示:

在此输入图像描述

是的,这个解决方案适用于所有Lollipop和前棒棒糖设备.

以下是证据: 在此输入图像描述

它重新调整大小而不是向上推动布局.所以希望,我帮助了和我在同一条船上的人.

非常感谢你们!

  • 你的解释中有一些误导.在所有Android版本中,键盘默认推送布局.不同的是,在你的左侧截图中它是android 4.1而在Android 4.1中系统栏总是黑色的,不能设置为透明而且适合系统窗口没有效果.您应该将Lollipop与KitKat进行比较. (2认同)

Mau*_*ycy 5

一些人遇到这个问题.

使用fitSystemWindows方法执行大量工作的关键信息:

此功能在层次结构中的遍历是深度优先的.相同的内容insets对象沿着层次结构向下传播,因此对其所做的任何更改都将被所有后续视图看到(包括层次结构中的上层视图,因为这是深度优先遍历).返回true的第一个视图将中止整个遍历.

因此,如果您有任何其他片段的内容视图,其中fitsSystemWindows设置为true,则可能会忽略该标志.如果可能的话,我会考虑让你的片段容器包含fitsSystemWindows标志.否则手动添加填充.