アプリケーションの種類によってはSystem Barを非表示にしたい場合があります。
例えば、没入したいゲームはStatus Barを非表示にして、システムからの割り込みを無くすことが望ましいでしょう。
System Barはデフォルトでアプリに表示されますが、プログラムで非表示にすることも可能です。
System Barの表示・非表示の制御について紹介します。
WindowInsetsControllerを使った制御
System barの表示・非表示の制御はWindowInsetsController#show( )/hide( )メソッドで行われます。
メソッドと引数に与えるパラメータは表の通りです。
メソッド | 引数A WindowInsets.Type.* | System Bar 非表示 | System Bar 表示 |
---|---|---|---|
hide(A) | statusBars() | Status Barの非表示 | |
navigationBars() | Navigation Barの非表示 | ||
systemBars() | System Barの非表示 | ||
show(A) | statusBars() | Status Barの表示 | |
navigationBars() | Navigation Barの表示 | ||
systemBars() | System Barの表示 | ||
※色はメソッドと引数が影響を及ぼす動作を表します。 |
また、非表示になったSystem Barを再表示させる操作方法はwindowInsetsController#systemBarsBehaviorへ指定するフラグにより変更できます。
フラグの動作は表の通りです。
フラグ BEHAVIOR_SHOW_* | System Bar 非表示 | System Bar 再表示 |
---|---|---|
BARS_BY_TOUCH (デフォルト) | Status Barの非表示 | 上端からスワイプで再表示 |
Navigation Barの非表示 | タッチで再表示 | |
System Barの非表示 (Status Bar) (Navigation Bar) | 上端からスワイプで再表示(*1) タッチで再表示 |
|
BARS_BY_SWIPE | Status Barの非表示 | 上端からスワイプで再表示 |
Navigation Barの非表示 | 下端からスワイプで再表示 | |
System Barの非表示 | 上下端からスワイプで再表示 | |
TRANSIENT_BARS_BY_SWIPE | Status Barの非表示 | 上端からスワイプで一定時間表示 ※黒の半透明 |
Navigation Barの非表示 | 下端からスワイプで一定時間表示 ※黒の半透明 |
|
System Barの非表示 | 上下端からスワイプで一定時間表示 ※黒の半透明 |
|
*1:スワイプは先にタッチが発生するのでNavigation Barが表示されてしまう ※色はフラグが影響を及ぼす動作を表します。 |
ただし、WindowInsetsController#show( )/hide( )はApi30で追加になったメソッドです。<Api30で用いていたView#systemUiVisibilityの代替になります。
System Barの表示・非表示
表示・非表示の実行例です。
非表示の様子は子Viewのレイアウト属性を参照してください。layout_marginとpaddingとgravityを使って実現されている事が分かります。
WindowInsets.Type.statusBars()
Status Barを非表示にします。
非表示にされたStatus Barは上端からのスワイプで再表示できます(デフォルト動作)。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... window.decorView.windowInsetsController?.apply { hide(WindowInsets.Type.statusBars()) } ... }
※LTRB : Left,Top,Right,Bottom
Class = DecorView Class = LinearLayout(Contents) Position = (0, 0) Size = 320x432 Layout Width, Height = -1,-1 Layout Margin LTRB = 0,0,0,48 Layout Gravity = -1 Padding LTRB = 0,0,0,0 Visibility = 0(Visible) Class = View(Navigation) Position = (0, 432) Size = 320x48 Layout Width, Height = -1,48 Layout Margin LTRB = 0,0,0,0 Layout Gravity = 80(Bottom) Padding LTRB = 0,0,0,0 Visibility = 0(Visible) Class = View(Status) Position = (0, 0) Size = 320x0 Layout Width, Height = -1,0 Layout Margin LTRB = 0,0,0,0 Layout Gravity = 48(Top) Padding LTRB = 0,0,0,0 Visibility = 4(Invisible)
Navigation Barを非表示にします。
非表示にされたNavigation Barは画面のタッチで再表示できます(デフォルト動作)。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... window.decorView.windowInsetsController?.apply { hide(WindowInsets.Type.navigationBars()) } ... }
※LTRB : Left,Top,Right,Bottom
Class = DecorView Class = LinearLayout(Contents) Position = (0, 0) Size = 320x480 Layout Width, Height = -1,-1 Layout Margin LTRB = 0,0,0,0 Layout Gravity = -1 Padding LTRB = 0,24,0,0 Visibility = 0(Visible) Class = View(Navigation) Position = (0, 480) Size = 320x0 Layout Width, Height = -1,0 Layout Margin LTRB = 0,0,0,0 Layout Gravity = 80(Bottom) Padding LTRB = 0,0,0,0 Visibility = 4(Invisible) Class = View(Status) Position = (0, 0) Size = 320x24 Layout Width, Height = -1,24 Layout Margin LTRB = 0,0,0,0 Layout Gravity = 48(Top) Padding LTRB = 0,0,0,0 Visibility = 0(Visible)
WindowInsets.Type.systemBars()
System Barを非表示にします。
非表示にされたStatus Barは上端からのスワイプで、navigation Barは画面のタッチで再表示できます(デフォルト動作)。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... window.decorView.windowInsetsController?.apply { hide(WindowInsets.Type.systemBars()) } ... }
※LTRB : Left,Top,Right,Bottom
Class = DecorView Class = LinearLayout Position = (0, 0) Size = 320x480 Layout Width, Height = -1,-1 Layout Margin LTRB = 0,0,0,0 Layout Gravity = -1 Padding LTRB = 0,0,0,0 Visibility = 0(Visible) Class = View Position = (0, 480) Size = 320x0 Layout Width, Height = -1,0 Layout Margin LTRB = 0,0,0,0 Layout Gravity = 80(Bottom) Padding LTRB = 0,0,0,0 Visibility = 4(Invisible) Class = View Position = (0, 0) Size = 320x0 Layout Width, Height = 1,0 Layout Margin LTRB = 0,0,0,0 Layout Gravity = 48(Top) Padding LTRB = 0,0,0,0 Visibility = 4(Invisible)
非表示⇒表示の切り替え
System Barを「非表示⇒表示」に切り替えます。
メソッドwindowInsetsController#show()を使います。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... window.decorView.windowInsetsController?.apply { // show(WindowInsets.Type.statusBars()) // show(WindowInsets.Type.navigationBars()) show(WindowInsets.Type.systemBars()) } ... }
System Barの再表示
非表示にしたSystem Barは画面の操作で再表示できます。その操作方法がwindowInsetsController#systemBarsBehaviorに指定するフラグにより決まります。
再表示の実行例です。
BEHAVIOR_SHOW_BARS_BY_TOUCH
非表示にされたStatus Barは上端からのスワイプで、Navigation Barは画面のタッチで再表示されます。
デフォルトの動作です。フラグの指定が無い場合はこの動作になります。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... window.decorView.windowInsetsController?.apply { hide(WindowInsets.Type.systemBars()) systemBarsBehavior = BEHAVIOR_SHOW_BARS_BY_TOUCH } ... }
BEHAVIOR_SHOW_BARS_BY_SWIPE
非表示にされたSystem Barは画面の上端または下端からのスワイプで再表示されます。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... window.decorView.windowInsetsController?.apply { hide(WindowInsets.Type.systemBars()) systemBarsBehavior = BEHAVIOR_SHOW_BARS_BY_SWIPE } ... }
BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
非表示にされたSystem Barは画面の上端または下端からのスワイプで再表示(黒の半透明)されます。ただし、一定時間の経過後に再び非表示になります。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... window.decorView.windowInsetsController?.apply { hide(WindowInsets.Type.systemBars()) systemBarsBehavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE } ... }
System Barの背面へコンテンツ表示
通常、System Barとコンテンツは重なり合いません。この重なり合いを許して、System Barの背面へコンテンツの表示が可能です。
方法はWindow#setDecorFitsSystemWindowsでfalseを指定します。setDecorFitsSystemWindows( )はApi30で追加になったメソッドです。
ただし、Sysytem Barを半透明にする必要があります。System Barの背面にあるコンテンツが見えなければ、意味が無いからです。
背面へコンテンツを表示する実行例です。
背面へ表示する様子は子Viewのレイアウト属性を参照してください。layout_marginとpaddingとgravityを使って実現されている事が分かります。
setDecorFitsSystemWindowsでfalse指定
System Barの背面にContents Viewが表示されます。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... window.setDecorFitsSystemWindows(false) ... // System Barの背景の透明度を変更 val _SystemBarColor = ContextCompat.getColor(this, R.color.barback) window.navigationBarColor = _SystemBarColor window.statusBarColor = _SystemBarColor ... }
<?xml version="1.0" encoding="utf-8"?> <resources> ... <color name="barback">#50ffffff</color> ... </resources>
※LTRB : Left,Top,Right,Bottom
Class = DecorView Class = LinearLayout Position = (0, 0) Size = 320x480 Layout Width, Height = -1,-1 Layout Margin LTRB = 0,0,0,0 Layout Gravity = -1 Padding LTRB = 0,0,0,0 Visibility = 0 Class = View Position = (0, 432) Size = 320x48 Layout Width, Height = -1,48 Layout Margin LTRB = 0,0,0,0 Layout Gravity = 80 Padding LTRB = 0,0,0,0 Visibility = 0 Class = View Position = (0, 0) Size = 320x24 Layout Width, Height = -1,24 Layout Margin LTRB = 0,0,0,0 Layout Gravity = 48 Padding LTRB = 0,0,0,0 Visibility = 0
関連記事: