3

Ich habe Probleme, wenn Sie Immersive-Modus verwenden und android:fitsSystemWindows="true" mit DrawerLayout verwenden. Ich muss dies auf True für die DrawerLayout und Symbolleiste auf die Systemleiste beschränkt werden.android: fitsSystemWindows = "true" hat Probleme mit der Verwendung von DrawerLayout und Immersive-Modus

Das Problem ist, ich habe eine Fragment, die die Anwendung auf Immersive-Modus setzt. Dies macht die App dies tun: Fullscreen with system bars

Welche ich weiß, ist ein bekanntes Problem mit android:fitsSystemWindows="true". Ich setze es auf false und Immersive-Modus funktioniert gut, aber die Symbolleiste und der Rest des Layouts ist nicht mehr auf die Systemleisten beschränkt. Ich versuche Ihnen den Wert zur Laufzeit und den unteren Teil des Layouts (auch bekannt als die Navigationsleiste Bereich) durch mein Layout gefüllt ist, aber das System Bar noch zeigt: Fullscreen with status bar

Hier ist mein Code:

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 - Hide and Show

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

Antwort

8

OK, endlich habe ich mein Problem behoben. Stellt sich heraus, dass ich die FLAG_FULLSCREEN Flagge hinzufügen musste. Hier ist mein Code für zukünftige Zuschauer:

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()); 
    } 
} 
+2

Ich sah mich nach verschiedenen Lösungen um, kam aber immer wieder auf Ihre Lösung zurück. Danke, dass du so viel von deinem Code gepostet hast.:) – miqueloi

+0

Dies ist die wichtigste Antwort auf dieses Problem. Allerdings habe ich festgestellt, dass in meinem Fall das erste Kind des Schubladenlayouts seine Ränder/Einfügungen nicht automatisch angepasst hat (seine Layout-Parameter waren auch keine regulären Layout-Parameter, sondern "DrawerLayout" -Parameter). Ich konnte es nur lösen, indem ich 'setMargins (0, 0, 0, 0);' auf seinen Layoutparametern aufrief. Wenn jemand anderes mit diesem Problem konfrontiert wird und eine elegantere Lösung hat, würde ich mich freuen, von Ihnen zu lernen! – Mdlc

1

Ich dachte, ich würde den folgenden Code der Konversation hinzufügen. Ich musste zwischen normalem und vollem Bildschirm wechseln und hatte immer wieder verschiedene Layout-Probleme. Dies wurde verursacht, weil DrawerLayoutsetFitsSystemWindows() in einem non-standard way verarbeitet. Der folgende Code hat erreicht, was ich brauchte.

Das erste Geheimnis war setFitsSystemWindows() auf den CoordinatorLayout anstelle der DrawerLayout in der XML-Datei zu ändern:

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

Das Thema in styles.xml<item name="android:windowTranslucentStatus">true</item> angeben soll.

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

In Java bekommen Griffe sowohl für die DrawerLayout und die CoordinatorLayout.

Diese App hat eine SupportActionBar. Wir brauchen einen Griff, damit er versteckt und offengelegt werden kann.

supportActionBar = getSupportActionBar(); 

den Status und die Navigationsleisten als durchscheinend Overlays So wechseln Sie den folgenden Code verwenden:

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

Alternativ vollständig zu wechseln den Status und die Navigationsleisten in immersiver Modus versteckt, den folgenden Code verwenden.

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); 
} 
Verwandte Themen