web-dev-qa-db-de.com

Die Navigation im immersiven Modus bleibt nach dem Drücken der Lautstärke oder dem Minimieren / Wiederherstellen hängen

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        this.getWindow().getDecorView().setSystemUiVisibility(getSystemUiFlags());
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    private static int getSystemUiFlags() {
            return View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
    }

}

Nach dem ersten Start

After first start

Nach Drücken der Lautstärketasten oder nach zweimaligem Drücken der letzten Apps

enter image description here

Ich habe gesehen, dass die QuickPic-App diesen Fehler nicht hat. Ich frage mich, wie sie es ausgelassen haben.

28

Der folgende Code funktioniert für mich:

public void updateUI() {
    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(
                        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);
                }
            }
        });
}

Und rief den Listener auf onCreate und onResume Methoden:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    updateUI();
}

@Override
public void onResume() {
    super.onResume();
    updateUI();
}
55
emjee

Meine Lösung besteht darin, die UI-Visibility-Flags an drei Stellen zu setzen:

  1. Bei der Fokussierung
  2. In onResume
  3. Im Listener OnSystemUiVisibilityChangeListener

Der dritte löste mein Problem. Die anderen werden vielleicht nicht gebraucht, aber ich habe sie verlassen. So sieht es aus:

  private void setupMainWindowDisplayMode() {
    View decorView = setSystemUiVisilityMode();
    decorView.setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
      @Override
      public void onSystemUiVisibilityChange(int visibility) {
        setSystemUiVisilityMode(); // Needed to avoid exiting immersive_sticky when keyboard is displayed
      }
    });
  }

  private View setSystemUiVisilityMode() {
    View decorView = getWindow().getDecorView();
    int options;
    options =
        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_STICKY;

    decorView.setSystemUiVisibility(options);
    return decorView;
  }

setupMainWindowDisplayMode () wird in onCreate () aufgerufen.

21
Chris

Ich hatte das gleiche Problem und löste es mit einem einfachen Workaround. Obwohl ich den theoretischen Grund für diese Problemumgehung nicht finden konnte, funktionierte es trotzdem für mich.

Es scheint, als würden beim Drücken einer Lautstärketaste die mit dem Immersive-Modus verbundenen Flags gelöscht. Und ich denke, deshalb ist der immersive Modus deaktiviert und der immersive Modus wird nicht automatisch wiederhergestellt.

Deshalb habe ich versucht, die 'Flags' zu setzen, nachdem ich die Lautstärketaste mit dem Objekt 'Runnable' gedrückt habe.

So funktioniert es:

immersiver Modus -> Lautstärketaste gedrückt (Flags gelöscht) -> 500ms später setzt das ausführbare Objekt die Flags erneut -> immersiver Modus wiederhergestellt

1. Definieren Sie zuerst das ausführbare Objekt, um die Flags zu setzen

private Runnable decor_view_settings = new Runnable()
{
    public void run() 
    {
        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);
    }
};

2. Senden Sie das ausführbare Objekt mit einiger Verzögerung an einen Handler, wenn eine Lautstärketaste gedrückt wird.

private Handler mHandler = new Handler();

...

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    if(keyCode == KeyEvent.KEYCODE_BACK)
    {
        finish();
    }
    else if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)
    {
        mHandler.postDelayed(decor_view_settings, 500);
    }

    return super.onKeyDown(keyCode, event);
}

Ich habe es nur ohne Grund für 500ms verzögert, es ist nicht wichtig.

. Der Basiscode für den immersiven Modus mit lauffähigem Objekt

@Override
public void onWindowFocusChanged(boolean hasFocus) 
{
    super.onWindowFocusChanged(hasFocus);

    if(hasFocus) 
    {
        mHandler.post(decor_view_settings);
    }
}

Auf meiner App hat es perfekt funktioniert.

Wenn ich also eine Lautstärketaste drücke, wird der Immersive-Modus deaktiviert und die Lautstärkewippe wird eingeblendet.

nach einigen Sekunden verschwindet die Lautstärkewippe, ebenso die Statusleiste und die Navigationsleiste.

Hoffe diese Arbeit für dich.

18
Sangseok