La navegación en modo inmersivo se vuelve pegajosa después de presionar el volumen o minimizar-restaurar

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

Después del primer inicio

Después del primer inicio

Después de presionar los botones de volumen o después de presionar dos veces las aplicaciones recientes

enter image description here

Vi que la aplicación QuickPic no tiene este error. Me pregunto cómo lo omitieron.

El siguiente código funciona para mí:

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

Y llamó al oyente en los métodos onCreate y onResume :

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

Tuve el mismo problema, y ​​lo resolví con una solución simple. Aunque no pude encontrar el motivo teórico de esta solución alternativa, de todos modos funcionó.

Parece que cuando se presiona un botón de volumen, se borran los ‘indicadores’ relacionados con el ‘modo inmersivo’. Y creo que es por eso que el modo inmersivo está desactivado y el modo inmersivo no se restaura automáticamente.

Por lo tanto, traté de establecer las ‘banderas’ después de presionar el botón de volumen con el objeto ‘ejecutable’.

Entonces, funciona así:

modo inmersivo -> botón de volumen presionado (banderas borradas) -> 500ms después, el objeto ejecutable establece los indicadores nuevamente -> modo inmersivo restaurado

1. Primero, defina el objeto ejecutable para establecer las banderas

 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. Publique el objeto ejecutable con cierta demora en un controlador cuando se presiona un botón de volumen

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

Lo retrasé por 500ms sin razón, no es importante.

3. El código básico para el modo inmersivo con objeto ejecutable

 @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if(hasFocus) { mHandler.post(decor_view_settings); } } 

Funcionó perfectamente en mi aplicación.

Por lo tanto, cuando presiono un botón de volumen, el modo de inmersión se desactiva y aparece el control de volumen.

después de unos segundos, el control de volumen desaparece y también lo hace la barra de estado y la barra de navegación.

Espero que este trabajo para ti.

Mi solución es establecer las banderas de IU-Visibilidad en tres lugares:

  1. Al obtener el enfoque
  2. En onResume
  3. En el oyente OnSystemUiVisibilityChangeListener

El tercero resolvió mi problema. Los otros podrían no ser necesarios, pero los dejé. Esto es lo que se ve así:

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

Se llama a setupMainWindowDisplayMode () en onCreate ().