たくさんの自由帳

よーこそtargetSdkVersion 30の世界へ

本題

Activityを全画面にしたり、ステータスバー、ナビゲーションを一時的に消すときにwindow?.decorView?.systemUiVisibilityがAndroid 11から非推奨になった
代わりにWindowInsetsControllerを使って消すらしい。

環境

なまえあたい
端末Pixel 3 XL
Android11 Beta 1

非表示の種類

  • スワイプすることで一時的にはステータスバー、ナビゲーションバーが表示され、数秒操作しないとまた自動で全画面に戻る
    • 動画アプリとか
    • WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPEを使う(後述)
  • スワイプして、ステータスバーを表示させるけどそのまま表示したままになる
    • どこで使ってるかはわからんな
    • WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPEを使う(後述)

つくる

スワイプすると一時的に表示される方
一時的に表示しているバーは半透明になっている。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    // Android 11 以上と分岐
    window?.insetsController?.apply {
        // スワイプで一時的に表示可能
        systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        // StatusBar + NavigationBar 非表示
        hide(WindowInsets.Type.systemBars())
        // ノッチにも侵略
        window?.attributes?.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
    }
} else {
    // Android 10 以前。
    window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
}

ノッチまでは広げなくていい場合は、ノッチにも侵略の一行をコメントアウトしてね。

もし一時的に表示ではなく、一回表示したらずっと出っぱなしにする際はsystemBarsBehavior

systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE

にすればいいと思います。

Type#systemBars()を使うと、ステータスバーとナビゲーションバーを消しますが、別に以下のコードでも動きます。

// ステータスバー
hide(WindowInsets.Type.statusBars())
// ナビゲーションバー
hide(WindowInsets.Type.navigationBars())

おまけ

IME(キーボードのこと)もこのWindowInsetsControllerを利用することで、一行で消せるようになりました。

window?.insetsController?.hide(WindowInsets.Type.ime())

キーボード隠すのなんか面倒だし成功したことないからこの方法が使えるのは嬉しい。🥳