web-dev-qa-db-fra.com

Android Masquer la barre de navigation/Rester en mode immersif avec l'apparence du clavier virtuel

Travailler sur l'application d'un client utilisant le mode immersif pour masquer la barre de navigation et la barre d'état de chaque activité à l'aide du code suivant:

int currentApiVersion = Android.os.Build.VERSION.SDK_INT;

final int flags = 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_STICKY;

// This work only for Android 4.4+
if (currentApiVersion >= 19) {

        getWindow().getDecorView().setSystemUiVisibility(flags);
        // Code below is for case when you press Volume up or Volume down.
        // Without this after pressing valume buttons navigation bar will
        // show up and don't hide
        final View decorView = getWindow().getDecorView();
        decorView
                .setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {

                    @Override
                    public void onSystemUiVisibilityChange(int visibility) {
                        if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                            decorView.setSystemUiVisibility(flags);
                        }
                }
         });
}

Le seul problème est qu'ils voudraient que l'application reste en mode immersif et ne montre pas la barre de navigation, même lorsque le clavier virtuel montre comment taper dans un EditText. Quelqu'un peut-il penser à un moyen de toujours avoir les boutons de navigation (clavier précédent/masqué, domicile, etc.) toujours masqués même lorsque vous utilisez le clavier?

19
ColossalChris

J'ai mis au point une solution de contournement qui vérifie le statut de la barre de navigation pour chaque interne, essayez de la masquer et de la vérifier à nouveau (et encore).

Voici un morceau de code qui garantit que la barre de navigation est masquée 2 secondes après la fermeture du clavier logiciel.

  private final Runnable checkSystemUiRunnable = new Runnable() {
    @Override
    public void run() {
      checkHideSystemUI();
    }
  };

  private void checkHideSystemUI() {
    // Check if system UI is shown and hide it by post a delayed handler
    if (isSystemUiShown) {
      hideSystemUI();
      handler.postDelayed(checkSystemUiRunnable, SYSTEM_UI_HIDE_DELAY);
    }
  }

  private void hideSystemUI() {
    decorView.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 // hide nav bar
                    | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                    | View.SYSTEM_UI_FLAG_IMMERSIVE);
  }

  // In onCreate()
    decorView.setOnSystemUiVisibilityChangeListener(
            new View.OnSystemUiVisibilityChangeListener() {
              @Override
              public void onSystemUiVisibilityChange(int visibility) {
                if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                  handler.postDelayed(checkSystemUiRunnable, SYSTEM_UI_HIDE_DELAY);
                  isSystemUiShown = true;
                } else {
                  isSystemUiShown = false;
                }
              }
            });
6
Mine

Voir this . J'ai cherché ce problème pendant plus de 3 heures et cette solution a bien fonctionné. J'espère que ça va être utile.

4
Aykut Burak SAFAK

Voici ma solution pour cela; J'ai d'abord vérifié si le clavier virtuel est affiché ou non:

getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {

                Rect r = new Rect();
                getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
                int screenHeight = getWindow().getDecorView().getRootView().getHeight();

                int keypadHeight = screenHeight - r.bottom;

                //Log.d(TAG, "keypadHeight = " + keypadHeight);

                if (keypadHeight > screenHeight * 0.15) { 
                     //Keyboard is opened
                     hideNavBar();
                }
                else {
                    // keyboard is closed
                }
            }
        });

Et j'ai une méthode hideNavBar () à déclencher lorsque le clavier logiciel est affiché.

private void hideNavBar() {
    if (Build.VERSION.SDK_INT >= 19) {
        View v = getWindow().getDecorView();
        v.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_STICKY);
    }
}

Cela résout le problème d'obtenir la barre de navigation alors qu'il y a un Edittext à taper.

1
Cem U

Mis à jour

J'ai une application de peinture ( Paint Shapes ) et c'est la configuration que j'avais l'habitude de rester en mode immersif. J'utilise la méthode onWindowFocusChanged.

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
        getWindow().getDecorView().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_STICKY);
    }
}
0
Benny