android:fitsSystemWindows="true" 在使用 DrawerLayout 和沉浸式模式时遇到问题
android:fitsSystemWindows="true" has issues with using DrawerLayout and immersive mode
我在尝试使用沉浸模式以及将 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;
}
好的,我终于解决了我的问题。原来我需要添加 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());
}
}
我想我会在对话中添加以下代码。我需要在正常查看和全屏之间切换,并且一直遇到各种布局困难。这是因为 DrawerLayout
在 non-standard way 中处理 setFitsSystemWindows()
。下面的代码完成了我所需要的。
第一个秘诀是修改 CoordinatorLayout
上的 setFitsSystemWindows()
而不是 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>
主题应在styles.xml
中指定<item name="android:windowTranslucentStatus">true</item>
。
<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);
}
我在尝试使用沉浸模式以及将 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;
}
好的,我终于解决了我的问题。原来我需要添加 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());
}
}
我想我会在对话中添加以下代码。我需要在正常查看和全屏之间切换,并且一直遇到各种布局困难。这是因为 DrawerLayout
在 non-standard way 中处理 setFitsSystemWindows()
。下面的代码完成了我所需要的。
第一个秘诀是修改 CoordinatorLayout
上的 setFitsSystemWindows()
而不是 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>
主题应在styles.xml
中指定<item name="android:windowTranslucentStatus">true</item>
。
<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);
}