7

Based on the following code snippet, I was wondering how to hide the soft keys (status and navigation bars) and maintain immersive mode throughout the whole app session even when an AlertDialog is displayed:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    AlertDialog.Builder dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dialog = new AlertDialog.Builder(this);

        findViewById(R.id.button).setOnClickListener(this);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            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);
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button:
                dialog.setTitle("Title");
                dialog.setMessage("Message");
                dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface arg0, int arg1) {

                        // Dismisses dialog.
                    }
                }).create().show();

                break;
        }
    }
}

... the soft keys remain hidden throughout the app until I press the button to display the dialog (takes the focus away) in which the soft keys show up and then later hides again after dismissing the dialog. Thanks a bunch.

DaveNOTDavid
  • 1,753
  • 5
  • 19
  • 37
  • Does this answer your question? [When using Immersive Mode with dialogs, nav. bar reappears and resizes my layout](https://stackoverflow.com/questions/22577654/when-using-immersive-mode-with-dialogs-nav-bar-reappears-and-resizes-my-layout) – zeitgeist Apr 21 '22 at 04:16

2 Answers2

2

Try this:

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.button:
            dialog.setTitle("Title");
            dialog.setMessage("Message");
            AlertDialog alert = dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface arg0, int arg1) {
                    // Dismisses dialog.
                }
            }).create();

            alert.getWindow().setFlags(
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
            alert.show();

            break;
    }
}

Or this:

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.button:
            dialog.setTitle("Title");
            dialog.setMessage("Message");
            AlertDialog alert = dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface arg0, int arg1) {
                    // Dismisses dialog.
                }
            }).create();

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                alert.getWindow().getDecorView()
                    .setSystemUiVisibility(
                          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);
            }
            alert.show();

            break;
    }
}
atiruz
  • 2,782
  • 27
  • 36
0

Use the following code to create your own immersive AlertDialog, and call it with alertDialog.showImmersive()

const val FLAGS_FULLSCREEN =
    View.SYSTEM_UI_FLAG_LOW_PROFILE or
            View.SYSTEM_UI_FLAG_FULLSCREEN or
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
            View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION

fun AlertDialog.showImmersive() {
    // Set the dialog to not focusable
    window?.setFlags(
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)

    // Make sure that the dialog's window is in full screen
    window?.decorView?.systemUiVisibility = FLAGS_FULLSCREEN

    // Show the dialog while still in immersive mode
    show()

    // Set the dialog to focusable again
    window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
}
hannes
  • 83
  • 5