在状态和导航栏后面显示内容 [英] Showing content behind status and navigation bar

查看:132
本文介绍了在状态和导航栏后面显示内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This looks like a duplicate question but I am not able to do it. I want complete transparent(not translucent) status bar as well as navigation bar and want the content to appear behind them.

activity_details.xml

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

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
        );

这就是我得到的.

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

How to get content behind the navigation bar?

如果我添加

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

转到我的styles.xml

to my styles.xml

这就是我得到的

如您所见,内容位于导航栏的后面,但是导航栏对此必须是半透明的.

As you can see, the content goes behind navigation bar but the navigation bar has to be translucent for this.

对此有什么解决办法吗?

Is there any solution for this?

推荐答案

在窗口中添加FLAG_LAYOUT_NO_LIMITS标志.这将适用于Android KitKat和更高版本的API.例如:

Add the FLAG_LAYOUT_NO_LIMITS flag within the Window. This will work for Android KitKat and above APIs. Example of this would be something like this:

 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标志允许窗口扩展到屏幕限制之外,因此导航栏也被该标志覆盖.

The reason why the FLAG_FULLSCREEN doesn't work is simply because the FULLSCREEN flag is for removing screen decors like status bar(which works for you). However Navigation bar is not a screen decor. The LAYOUT_NO_LIMIT flag allows the window to extend beyond the screen limit, hence Navigation bar also gets covered within this flag.

通过将应用程序设置为沉浸式模式,您也可以简单地隐藏导航和状态栏.

Also you could simply hide the navigation and status bar by setting the app in immersive mode.

编辑 API ViewCompat.setOnApplyWindowInsetListener解决了android:fitsSystemWindows=true不能解决的问题,并且可以将窗口插图应用于特定视图.一个例子.

EDIT The API ViewCompat.setOnApplyWindowInsetListener solves issues which the android:fitsSystemWindows="true" does not and window insets can be applied to a particular view. An example of this.

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

FrameLayoutLinearLayoutRelativeLayout之类的标准布局不会将窗口插图传递给其子级,而材质布局会(例如DrawerLayoutCoordinatorLayout)进行传递.因此,我们可以将布局更改为任何重要的布局,也可以将标准布局子类化,然后将插图自己传递给布局的子级.我们只需要重写onApplyWindowInsets方法.

Standard layouts like FrameLayout , LinearLayout or RelativeLayout will not pass window insets to their children, whereas material layouts will do (e.g. DrawerLayout , CoordinatorLayout ). So we can change our layout to any material one, or we can subclass a standard layout and pass the insets to the children of layout ourselves. We just have to override onApplyWindowInsets method.

@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;
}

参考文档: OnApplyWindowInsetsListener 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆