アプリケーションの種類によっては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
関連記事:
