動画、ゲーム、画像ギャラリー、書籍、プレゼンテーションのスライドなどのコンテンツでは、全画面表示がユーザーに最良のエクスペリエンスを与える場合があります。このページでは、全画面表示を利用してユーザーに没入型のコンテンツを提供しつつ、ユーザーが誤ってアプリを終了するのを防ぐ方法について説明します。

アプリの画面サイズを最大化するために全画面モードを有効にしたいと考えるのは自然ですが、ユーザーが通知のチェックやちょっとした検索のためにしばしばアプリを出たり入ったりすることにも留意する必要があります。全画面表示を使用すると、ユーザーはシステム ナビゲーションに簡単にアクセスできなくなります。そのため、全画面モードを使用するのは、単に表示領域を少し広げるためだけではなく、それ以上のユーザー エクスペリエンス面のメリットがある場合に限るようにしてください(誤ってゲームを終了するのを避けるため、画像や動画、書籍で魅力的な没入型エクスペリエンスを提供するためなど)。
全画面表示オプション
Android には、アプリを全画面表示にする方法として「観賞モード」、「没入モード」、「アプリ優先型没入モード」という 3 つのオプションがあります。3 つのアプローチすべてにおいて、システムバーは非表示になりますが、実行中のアクティビティは引き続きすべてのタッチイベントを受信します。 各アプローチの違いは、ユーザーがシステムバーを再表示する方法にあります。
以下では、各オプションの詳細について説明します。サンプルコードについては、全画面モードを有効にするをご覧ください。
観賞モード

観賞モードは、動画を視聴しているときなど、ユーザーが画面を頻繁に操作しない場合の全画面表示用です。
ユーザーがシステムバーを元に戻したい場合は、画面内の任意の場所をタップするだけです。
観賞モードを有効にするには、setSystemUiVisibility()
を呼び出して SYSTEM_UI_FLAG_FULLSCREEN
とSYSTEM_UI_FLAG_HIDE_NAVIGATION
を渡します。
システムバーを再表示する際、コールバックを受信することで、必要に応じて他の部分についても UI を更新することができます。詳細については、UI の表示設定変更に応答するをご覧ください。
没入モード


没入モードは、ユーザーが画面を頻繁に操作するアプリを対象としています。 たとえば、ゲームをプレイしているときや、ギャラリー内で画像を表示するとき、書籍やプレゼンテーションのスライドなど、ページ付きコンテンツを読むときなどが該当します。
ユーザーがシステムバーを元に戻す必要がある場合は、システムバーが隠れている画面の端からスワイプします。このように明白に意図的な操作を要求することにより、ちょっとしたタップミスやスワイプミスでユーザーのアプリ利用が中断されることがなくなります。
没入モードを有効にするには、setSystemUiVisibility()
を呼び出して、SYSTEM_UI_FLAG_IMMERSIVE
フラグに SYSTEM_UI_FLAG_FULLSCREEN
と SYSTEM_UI_FLAG_HIDE_NAVIGATION
を組み合わせて渡します。
アプリ内に独自のコントロールを設置している場合、ユーザーが没入モードでコンテンツを楽しむうえで不要であるならば、システムバーと同期して非表示と再表示を行うようにしてください。 また、アプリ固有の操作でアプリ コントロールの表示 / 非表示を切り替えるようにしている場合も、同じように同期することをおすすめします。たとえば、画面内の任意の場所をタップすることでツールバーやパレットの表示 / 非表示が切り替わるのであれば、システムバーの表示 / 非表示も一緒に切り替わる必要があります。
システムバーを再表示する際、コールバックを受信することで、必要に応じて他の部分についても UI を更新することができます。詳細については、UI の表示設定変更に応答するをご覧ください。
アプリ優先型没入モード
通常の没入モードの場合、ユーザーが画面の端からスワイプすると、システムはその操作を認識してシステムバーを表示しますが、アプリは操作が発生したことを認識しません。そのため、多数のスワイプ操作が必要なゲームをプレイする場合や、描画アプリを使用する場合など、アプリの中核的機能の一部としてユーザーが実際に画面の端からスワイプする必要がある場合は、通常の没入モードではなく、「アプリ優先型」の没入モードを有効にする必要があります。
アプリ優先型没入モードの場合、ユーザーが画面の端からスワイプすると、システムバーは表示されますが半透明の状態になります。タップ操作はアプリに渡されるので、アプリも操作に対応できます。
たとえば、このアプローチを使用する描画アプリでは、画面の端から始まる線をユーザーが描きたい場合、画面の端からスワイプするとシステムバーが表示され、それと同時に、画面の端から始まる線の描画も開始されます。システムバーに対して数秒間操作が行われなかった場合や、ユーザーがシステムバー以外の部分でタップなどの操作を行った場合、システムバーは自動的に非表示になります。
アプリ優先型没入モードを有効にするには、setSystemUiVisibility()
を呼び出して、SYSTEM_UI_FLAG_IMMERSIVE_STICKY
フラグに SYSTEM_UI_FLAG_FULLSCREEN
と SYSTEM_UI_FLAG_HIDE_NAVIGATION
を組み合わせて渡します。
アプリ優先型没入モードを使用している場合、システム UI の表示設定が変更されたときにコールバックを受信することはできません。アプリ優先型没入モードの自動非表示動作を使用したいが、その一方で独自の UI コントロールを表示するためにシステム UI がいつ再表示されるかを知りたい場合は、通常の IMMERSIVE
フラグを指定し、Handler.postDelayed()
などを使用して数秒後に再び没入モードに入ります。
全画面モードの有効化
どの全画面モードを使用する場合でも、setSystemUiVisibility()
を呼び出して SYSTEM_UI_FLAG_HIDE_NAVIGATION
または SYSTEM_UI_FLAG_FULLSCREEN
(あるいはその両方)を渡す必要があります。SYSTEM_UI_FLAG_IMMERSIVE
を指定すると通常の没入モード、SYSTEM_UI_FLAG_IMMERSIVE_STICKY
を指定するとアプリ優先型没入モードが有効になります。いずれも指定しなければ、観賞モードが有効になります。
他のシステム UI フラグ(SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
や SYSTEM_UI_FLAG_LAYOUT_STABLE
など)を追加することをおすすめします。それにより、システムバーの表示 / 非表示が切り替わったときにレイアウトのサイズを維持できます。また、アクションバーや他の UI コントロールも同時に非表示にする必要があります。
画面領域の変化に応じてレイアウトのサイズを変更することなく、アクティビティ内でステータスバーとナビゲーション バーの非表示 / 表示を切り替える方法を以下のコードに示します。
Kotlin
override fun onWindowFocusChanged(hasFocus: Boolean) { super.onWindowFocusChanged(hasFocus) if (hasFocus) hideSystemUI() } private fun hideSystemUI() { // Enables regular immersive mode. // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE. // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE // Set the content to appear under the system bars so that the // content doesn't resize when the system bars hide and show. or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // Hide the nav bar and status bar or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN) } // Shows the system bars by removing all the flags // except for the ones that make the content appear under the system bars. private fun showSystemUI() { window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) }
Java
@Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { hideSystemUI(); } } private void hideSystemUI() { // Enables regular immersive mode. // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE. // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_IMMERSIVE // Set the content to appear under the system bars so that the // content doesn't resize when the system bars hide and show. | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // Hide the nav bar and status bar | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN); } // Shows the system bars by removing all the flags // except for the ones that make the content appear under the system bars. private void showSystemUI() { View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); }
また、以下のように実装すると、ユーザー エクスペリエンスの質を高めることができます。
- 状態間の遷移をシームレスにするため、すべての UI コントロールの表示 / 非表示をシステムバーと同期させます。アプリが没入モードに入ったらすべての UI コントロールがシステムバーとともに非表示になり、システム UI が再表示されたら一緒に再表示されるようにします。そのためには、UI の表示設定変更に応答するで説明されているように、
View.OnSystemUiVisibilityChangeListener
を実装してコールバックを受信します。 onWindowFocusChanged()
を実装します。ウィンドウ フォーカスを取得する際は、システムバーを再度非表示にすることをおすすめします。たとえば、アプリの上にダイアログやポップアップ メニューが表示されてウィンドウ フォーカスが失われた場合は、Handler.postDelayed()
などを使用して以前スケジュールしていた保留中の「非表示」オペレーションをキャンセルします。onSingleTapUp(MotionEvent)
を検出するGestureDetector
を実装し、ユーザーがコンテンツをタップすることでシステムバーの表示 / 非表示を手動で切り替えられるようにします。シンプルなクリック リスナーは、ユーザーが画面上で指をドラッグしただけでもトリガーされるため、この場合には適していません(クリック ターゲットが画面全体を占有していると想定されます)。
注: SYSTEM_UI_FLAG_IMMERSIVE_STICKY
フラグを使用している場合、スワイプによりシステム UI は一時的に半透明の状態で表示されますが、フラグはクリアされず、システム UI 表示設定変更リスナーはトリガーされません。
他のサンプルコード
各種の全画面モードを使用したコードについては、以下のサンプルをご覧ください。
他の注意事項
Android Automotive OS の場合、自動車メーカーは全画面モードをブロックできます。