在状态和导航栏后面显示内容 [英] Showing content behind status and navigation bar
问题描述
这看起来像是一个重复的问题,但我无法做到.我想要完整的透明(而不是半透明)状态栏以及导航栏,并希望内容显示在它们的后面.
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();
});
FrameLayout
,LinearLayout
或RelativeLayout
之类的标准布局不会将窗口插图传递给其子级,而材质布局会(例如DrawerLayout
,CoordinatorLayout
)进行传递.因此,我们可以将布局更改为任何重要的布局,也可以将标准布局子类化,然后将插图自己传递给布局的子级.我们只需要重写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 , 查看全文