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;
}
}
Après le premier démarrage
Après avoir appuyé deux fois sur les boutons de volume ou appuyé deux fois sur les applications récentes
J'ai vu que l'application QuickPic n'a pas ce bug. Je me demande comment ils l'ont omis.
Le code suivant fonctionne pour moi:
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);
}
}
});
}
Et a appelé l'écouteur sur les méthodes onCreate
et onResume
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
updateUI();
}
@Override
public void onResume() {
super.onResume();
updateUI();
}
Ma solution consiste à définir les drapeaux UI-Visibility à trois endroits:
Le troisième a résolu mon problème. Les autres pourraient ne pas être nécessaires, mais je les ai laissés. Voici à quoi ça ressemble:
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 () est appelé dans onCreate ().
J'ai eu le même problème et je l'ai résolu avec une solution de contournement simple. Même si je n'ai pas pu trouver la raison théorique de cette solution de contournement, mais cela a quand même fonctionné pour moi.
Il semble que lorsqu'une touche de volume est enfoncée, les "drapeaux" liés au "mode immersif" sont effacés. Et je pense que c'est pourquoi le mode immersif est désactivé et le mode immersif n'est pas restauré automatiquement.
Par conséquent, j'ai essayé de définir les "drapeaux" après avoir appuyé sur le bouton de volume avec l'objet "exécutable".
Donc, cela fonctionne comme ceci:
mode immersif -> bouton de volume enfoncé (drapeaux effacés) -> 500 ms plus tard, l'objet exécutable définit à nouveau les drapeaux -> mode immersif restauré
1. Tout d'abord, définissez l'objet exécutable pour définir les drapeaux
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. Publiez l'objet exécutable avec un certain retard à un gestionnaire quand un bouton de volume est pressé
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);
}
Je l'ai juste retardé de 500 ms sans raison, ce n'est pas important.
. Le code de base pour le mode immersif avec un objet exécutable
@Override
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
if(hasFocus)
{
mHandler.post(decor_view_settings);
}
}
Cela a parfaitement fonctionné sur mon application.
Ainsi, lorsque j'appuie sur un bouton de volume, le mode immersif est désactivé et la bascule de volume apparaît.
après quelques secondes, la bascule du volume disparaît, de même que la barre d'état et la barre de navigation.
J'espère que ce travail pour vous.