尝试使用沉浸式模式并将android:fitsSystemWindows="true"
与DrawerLayout
一起使用时,我遇到了问题。我必须将此设置为true才能将DrawerLayout
和工具栏限制为系统栏。
问题是,我有Fragment
将应用程序设置为沉浸式模式。这使得应用程序执行此操作:
我所知道的是android:fitsSystemWindows="true"
的已知问题。我将其设置为false
,沉浸式模式运行良好,但工具栏和布局的其余部分不再受制于系统条。我尝试在运行时设置值,布局的下半部分(也就是导航栏区域)由我的布局填充,但系统栏区域仍然显示:
这是我的代码:
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
ClockFragment.java - 隐藏和显示
private void hideSystemUI() {
if (Build.VERSION.SDK_INT >= 14) {
getActivity().findViewById(R.id.drawer_layout).setFitsSystemWindows(false);
}
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (Build.VERSION.SDK_INT >= 19) {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE);
} else if (Build.VERSION.SDK_INT >= 16) {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
} else {
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
toolbar.setVisibility(View.GONE);
layoutParams.screenBrightness = -1.00f;
getActivity().getWindow().setAttributes(layoutParams);
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
uiShowing = false;
dimming = false;
screenMode = 1;
}
private void hideSystemUIAndDim() {
if (Build.VERSION.SDK_INT >= 14) {
getActivity().findViewById(R.id.drawer_layout).setFitsSystemWindows(false);
}
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (Build.VERSION.SDK_INT >= 19) {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE);
} else if (Build.VERSION.SDK_INT >= 16) {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
} else {
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
toolbar.setVisibility(View.GONE);
layoutParams.screenBrightness = 0.01f;
getActivity().getWindow().setAttributes(layoutParams);
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
uiShowing = false;
dimming = true;
screenMode = 2;
}
private void showSystemUI() {
if (Build.VERSION.SDK_INT >= 14) {
getActivity().findViewById(R.id.drawer_layout).setFitsSystemWindows(true);
}
if (Build.VERSION.SDK_INT >= 16) {
mDecorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} else {
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
toolbar.setVisibility(View.VISIBLE);
layoutParams.screenBrightness = -1.00f;
getActivity().getWindow().setAttributes(layoutParams);
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
uiShowing = true;
dimming = false;
screenMode = 0;
}
答案 0 :(得分:8)
好的,我终于解决了我的问题。事实证明我需要添加FLAG_FULLSCREEN
标志。这是我未来观众的固定代码:
private void hideSystemUI() {
if (Build.VERSION.SDK_INT >= 14) {
drawerLayout.setFitsSystemWindows(false);
}
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (Build.VERSION.SDK_INT >= 19) {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE);
} else if (Build.VERSION.SDK_INT >= 16) {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
}
toolbar.setVisibility(View.GONE);
layoutParams.screenBrightness = -1.00f;
getActivity().getWindow().setAttributes(layoutParams);
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
uiShowing = false;
dimming = false;
screenMode = 1;
}
private void hideSystemUIAndDim() {
if (Build.VERSION.SDK_INT >= 14) {
drawerLayout.setFitsSystemWindows(false);
}
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (Build.VERSION.SDK_INT >= 19) {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE);
} else if (Build.VERSION.SDK_INT >= 16) {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
}
toolbar.setVisibility(View.GONE);
layoutParams.screenBrightness = 0.01f;
getActivity().getWindow().setAttributes(layoutParams);
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
uiShowing = false;
dimming = true;
screenMode = 2;
}
private void showSystemUI() {
try {
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (Build.VERSION.SDK_INT >= 14) {
drawerLayout.setFitsSystemWindows(true);
}
if (Build.VERSION.SDK_INT >= 16) {
mDecorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
toolbar.setVisibility(View.VISIBLE);
layoutParams.screenBrightness = -1.00f;
getActivity().getWindow().setAttributes(layoutParams);
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
uiShowing = true;
dimming = false;
screenMode = 0;
} catch (NullPointerException e) {
Log.e(TAG, e.toString());
}
}
答案 1 :(得分:1)
我以为我会在会话中添加以下代码。我需要在正常观看和全屏之间切换,并且保持各种布局困难。造成这种情况的原因是DrawerLayout
处理了non-standard way中的setFitsSystemWindows()
。以下代码完成了我的需要。
第一个秘密是修改setFitsSystemWindows()
上的CoordinatorLayout
而不是XML文件中的DrawerLayout
:
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawerlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent" >
<!-- android:fitsSystemWindows="true" moves rootCoordinatorLayout below the system status bar.
When it is specified the theme should include <item name="android:windowTranslucentStatus">true</item>. -->
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinatorlayout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fitsSystemWindows="true" >
<!-- Include other layouts specific to the app. -->
</android.support.design.widget.CoordinatorLayout>
<!-- The navigation drawer. -->
<android.support.design.widget.NavigationView
android:id="@+id/navigationview"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
app:headerLayout="@layout/navigation_header"
app:menu="@menu/navigation_menu" />
</android.support.v4.widget.DrawerLayout>
主题应在<item name="android:windowTranslucentStatus">true</item>
中指定styles.xml
。
<resources>
<!-- `android:windowTranslucentStatus` makes the system status bar translucent.
When it is specified the root layout should include android:fitsSystemWindows="true". -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
</style>
</resources>
在Java中,获取DrawerLayout
和CoordinatorLayout
的句柄。
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout);
CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorlayout);
此应用拥有SupportActionBar
。我们需要一个处理它,以便它可以隐藏和显示。
supportActionBar = getSupportActionBar();
要将状态和导航栏切换为半透明叠加层,请使用以下代码:
if (supportActionBar.isShowing()) { // If `supportActionBar` is visible, switch to full screen mode.
// Hide `supportActionBar`.
supportActionBar.hide();
// Set `coordinatorLayout` to fit under the status and navigation bars.
coordinatorLayout.setFitsSystemWindows(false);
// Set the navigation bar to be translucent.
// There is an Android Support Library bug that causes a scrim to print on the right side of the `Drawer Layout` when the navigation bar is displayed on the right of the screen.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
} else { // Switch to normal viewing mode.
// Show `supportActionBar`.
supportActionBar.show();
// Constrain `coordinatorLayout` inside the status and navigation bars.
coordinatorLayout.setFitsSystemWindows(true);
// Remove the translucent navigation bar flag.
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
或者,要在沉浸式模式下切换完全隐藏状态和导航栏,请使用以下代码。
if (supportActionBar.isShowing()) { // If `supportActionBar` is visible, switch to full screen mode.
// Hide `supportActionBar`.
supportActionBar.hide();
// Remove the translucent overlays.
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// Remove the translucent status bar overlay on the `Drawer Layout`, which is special and needs its own command.
drawerLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
/* SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
* SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
* SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically rehides them after they are shown.
*/
coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
// Set `coordinatorLayout` to fill the whole screen.
CoordinatorLayout.setFitsSystemWindows(false);
} else { // Switch to normal viewing mode.
// Show `supportActionBar`.
supportActionBar.show();
// Add the translucent status flag if it is unset. This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// Remove the `SYSTEM_UI` flags from `coordinatorLayout`.
coordinatorLayout.setSystemUiVisibility(0);
// Constrain `coordinatorLayout` inside the status and navigation bars.
coordinatorLayout.setFitsSystemWindows(true);
}