[Android & Kotlin] 全画面モードの systemUiVisibility (API29まで)

API 30 からは全画面モードに使っていたsystemUiVisibilityが非推奨になりました。代わりに windowInsetsControlle を使いますが、下位互換ではないのでAPI29までは切り替えて使う必要があります。

Android Studio 4.1.3
API 29

 

000000047128 - [Android & Kotlin] 全画面モードの systemUiVisibility (API29まで)impression?a id=2545324&p id=969&pc id=1263&pl id=47128 - [Android & Kotlin] 全画面モードの systemUiVisibility (API29まで) R904D.E24336V - [Android & Kotlin] 全画面モードの systemUiVisibility (API29まで)

Fullscreen

 
ゲームやギャラリーなどは全画面での表示が好まれるアプリです。単純に全画面にするとユーザーが困ることもあり、3つの方法がGoogleから提示されています。

fullscreen 01 - [Android & Kotlin] 全画面モードの systemUiVisibility (API29まで)
 

コードでのfullscreenにはAPIが19以上という制約がありますが、API19未満のシェアは相当少なくなってきています。
 
例えば、この画像をフルスクリーンで表示したいとすると、
 
girl tomoka 169x300 - [Android & Kotlin] 全画面モードの systemUiVisibility (API29まで)
 
これを普通に表示させるとこうなります
 
original - [Android & Kotlin] 全画面モードの systemUiVisibility (API29まで)
 
フルスクリーンにするには3種類のバーを非表示にする必要があります。

  • ステータスバー
  • タイトルバー
  • ナビゲーションバー

Enable fullscreen mode | Android Developers によると幾つかのアプローチがあると言っていますので、それぞれ試してみます。
 

 

Lean back

 
Lean backと言われている観賞モードです。ユーザーが画面を頻繁に操作しない例えば動画などでの全画面表示です。

setSystemUiVisibility() から status bar と navigation bar の設定で非表示にできます。

  • SYSTEM_UI_FLAG_FULLSCREEN
    • statusbarを非表示
  • SYSTEM_UI_FLAG_HIDE_NAVIGATION
    • navigationbarを非表示

また、全画面から戻ったり終了させるためには、画面をタップして戻ることが可能です。
このシステムバーの表示、非表示はリスナーを使ってステータスを知ることができます。
setOnSystemUiVisibilityChangeListener
 
なお、タイトルバーはここでは外しておくためにMainActivityの継承はActivity()とします。(AppCompatActivityは全画面表示モードで使います)
 
MainActivity.kt

 
あまり関係ないとは思いますがレイアウトです。
activity_main.xml

 

 
起動時はフルスクリーンとなっており、”The system bars are NOT visible”のログが見て取れます。
画面タップで”The system bars are visible”とログが代わり、ステータスバーとナビゲーションバーが現れました。

 

没入モード

 
ゲームに没頭している(immersive)時に使うということでしょうか、
SYSTEM_UI_FLAG_IMMERSIVE
これを使うと画面を内側のスワイプダウンでフルスクリーンが解除されます。

  • SYSTEM_UI_FLAG_IMMERSIVE
  • SYSTEM_UI_FLAG_FULLSCREEN
  • SYSTEM_UI_FLAG_HIDE_NAVIGATION

MainActivity.kt

 

 

アプリ優先型没入モード

 
immersiveは、ゲームなどで頻繁に画面をスワイプするような場合などでシステムバー(ステータスバーやナビゲーションバー)が出てくると煩わしくなります。これを軽減するためにSYSTEM_UI_FLAG_IMMERSIVE_STICKYを使うことができます。
 
完全にはシステムバーにならない半透明な状態で何もしなければ数秒で元に戻ります。

  • SYSTEM_UI_FLAG_IMMERSIVE_STICKY
  • SYSTEM_UI_FLAG_FULLSCREEN
  • SYSTEM_UI_FLAG_HIDE_NAVIGATION

MainActivity.kt

 

 

Fullscreen Mode

 
Activity()ではなくAppCompatActivity()を使いたい場合もあります。SYSTEM_UI_FLAG_LAYOUT_STABLE
を使うとタイトルバーを消せるのですが、これだけだと問題があります。
 
fullscreen 02 - [Android & Kotlin] 全画面モードの systemUiVisibility (API29まで)
 
画面の status bar, navigation bar にスペースができてしまいます。これを解消するには
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
これらはあたかもシステムバーが非表示であるかのようにビューをレイアウトしてくれるというものです。

  • SYSTEM_UI_FLAG_IMMERSIVE_STICKY
  • SYSTEM_UI_FLAG_FULLSCREEN
  • SYSTEM_UI_FLAG_HIDE_NAVIGATION
  • SYSTEM_UI_FLAG_LAYOUT_STABLE
  • SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
  • SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

また、DialogやPop up メニューなどによってこれらが阻害されないように、onWindowFocusChanged(hasFocus: Boolean)を使って非表示を遅らせることが必要な場合もあります。
これらをまとめると、
MainActivity.kt

 
これでフルスクリーン表示ができました。
 
fullscreen 01 - [Android & Kotlin] 全画面モードの systemUiVisibility (API29まで)
 
API30 以上は以下を参考にしてAPIで切り分けてください
 

アプリによって、ゲームやギャラリーなどは全画面での表示が好まれるケースがあります。ステータスバーやナビゲーションバーが消えてくれると見やすい...

 
 
 
References:
Enable fullscreen mode | Android Developers
Control the system UI visibility | Android Developers