显示状态和导航栏后面的内容

时间:2017-08-05 23:26:07

标签: android navigationbar android-statusbar

这看起来像一个重复的问题,但我无法做到。我想要完整的透明(不是半透明)状态栏以及导航栏,并希望内容显示在它们后面。

activity_details.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary"
    tools:context="com.bitspilanidvm.bosm2017.DetailsActivity">

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/q"
    android:scaleType="centerCrop"/>

</LinearLayout>

v21 styles.xml

<resources>

<!-- Theme for API level > 21 -->
<style name="AppTheme" parent="AppBaseTheme">
     <!--Customize your theme here. -->
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:navigationBarColor">@android:color/transparent</item>
</style>

在活动java文件

getWindow().getDecorView().setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
               View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        );

这就是我得到的。

enter image description here

如何获取导航栏后面的内容?

如果我添加

<item name="android:windowTranslucentNavigation">true</item>

到我的styles.xml

这是我得到的

enter image description here

正如您所看到的,内容位于导航栏后面,但导航栏必须是半透明的。

有没有解决方案?

3 个答案:

答案 0 :(得分:14)

在窗口中添加FLAG_LAYOUT_NO_LIMITS标志。这适用于Android KitKat及以上的API。例如:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        Window window = getWindow(); 
     window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    }

FLAG_FULLSCREEN不起作用的原因仅仅是因为FULLSCREEN标志用于删除屏幕装饰,如状态栏(适用于您)。但导航栏不是屏幕装饰。 LAYOUT_NO_LIMIT标志允许窗口超出屏幕限制,因此导航栏也会被覆盖在此标志内。

您也可以通过将应用程序设置为沉浸式模式来隐藏导航和状态栏。

修改 API ViewCompat.setOnApplyWindowInsetListener解决了android:fitsSystemWindows=”true”没有的问题,窗口插入可以应用于特定视图。这方面的一个例子。

ViewCompat.setOnApplyWindowInsetsListener(toolbar, (v, insets) -> {
    ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
    params.topMargin = insets.getSystemWindowInsetTop();
    return insets.consumeSystemWindowInsets();
});

FrameLayoutLinearLayoutRelativeLayout等标准布局不会将窗口插件传递给他们的子节点,而材质布局会这样做(例如DrawerLayoutCoordinatorLayout )。因此,我们可以将布局更改为任何材质,或者我们可以将标准布局子类化并将插图传递给布局的子项。我们只需要覆盖onApplyWindowInsets方法。

@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
    int childCount = getChildCount();
    for (int index = 0; index < childCount; ++index)
        getChildAt(index).dispatchApplyWindowInsets(insets); 
        // let children know about WindowInsets

    return insets;
}

参考文档:OnApplyWindowInsetsListenerWindowInsets

答案 1 :(得分:2)

我想评论接受的答案,但我还不能。

只是警告所有采取这种方法的人

FLAG_LAYOUT_NO_LIMITS允许您将根视图扩展到屏幕边界之外,从而产生对布局设计的其他担忧。例如,这个标志只是通过强制系统忽略&#34; adjustPan&#34;来破坏表格的可读性。和&#34; adjustResize&#34;标志

所以,尽管我仍然认为Ahbi的回答是正确的,但请确保没有任何内容超出此标志的范围

更好的解决方案:

实际上,我发现了一种更好的方法来实现相同的结果,而不会破坏任何东西

这是我的样式文件

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:navigationBarColor">@android:color/transparent</item>

</style>

这些是我以编程方式设置的标志

w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
w.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);

设置标志LAYOUT_HIDE_NAVIGATION(与样式项结合使用)可以解决问题,我的表单仍然会对adjustPan标志做出反应

答案 2 :(得分:0)

如果要在状态栏后面显示图像

getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

但这样做fitsSystemWindows="true"无效 工具栏与状态栏重叠。