ステータスバーを非表示にする

このレッスンでは、さまざまなバージョンの Android でステータスバーを非表示にする方法について説明します。ステータスバー(ならびに、必要に応じてナビゲーション バー)を非表示にすると、コンテンツが利用できる表示領域が増えるため、没入型のユーザー エクスペリエンスを実現できるようになります。

ステータスバーを表示した状態のアプリを図 1 に示します。

システムバー

図 1. 表示状態のステータスバー

ステータスバーを非表示にした状態のアプリを図 2 に示します。なお、アクションバーも非表示になっています。ステータスバーを非表示にした場合は、アクションバーを表示しないでください。

システムバー

図 2. 非表示状態のステータスバー

ステータスバーを非表示にする(Android 4.0 以前)

Android 4.0(API レベル 14)以前の場合、WindowManager フラグをセットすることで、ステータスバーを非表示にできます。これは、プログラムで行うか、アプリのマニフェスト ファイル内でアクティビティ テーマを設定することで実行できます。アプリ内でステータスバーを常に非表示にする場合は、アプリのマニフェスト ファイル内でアクティビティ テーマを設定することをおすすめします(必要に応じて、プログラムでテーマをオーバーライドできます)。たとえば、次のようになります。

    <application
        ...
        android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" >
        ...
    </application>
    

アクティビティ テーマを使用した場合、次のようなメリットがあります。

  • プログラムでフラグをセットするよりも、メンテナンスが簡単で、エラーを低減することができます。
  • アプリのメイン アクティビティをインスタンス化する前に、UI のレンダリングに必要な情報をシステムが入手できるため、UI の遷移がスムーズになります。

あるいは、プログラムで WindowManager フラグをセットすることもできます。このアプローチの場合、ユーザーがアプリを操作したときに、ステータスバーの非表示 / 表示を簡単に切り替えることができます。

Kotlin

    class MainActivity : Activity() {

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            // If the Android version is lower than Jellybean, use this call to hide
            // the status bar.
            if (Build.VERSION.SDK_INT < 16) {
                window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                        WindowManager.LayoutParams.FLAG_FULLSCREEN)
            }
            setContentView(R.layout.activity_main)
        }
        ...
    }
    

Java

    public class MainActivity extends Activity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // If the Android version is lower than Jellybean, use this call to hide
            // the status bar.
            if (Build.VERSION.SDK_INT < 16) {
                getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                        WindowManager.LayoutParams.FLAG_FULLSCREEN);
            }
            setContentView(R.layout.activity_main);
        }
        ...
    }
    

アクティビティ テーマを利用した場合、またはプログラムで実行した場合のいずれの場合でも、WindowManager フラグをセットすると、アプリがフラグをクリアしない限り、フラグは有効な状態を維持します。

FLAG_LAYOUT_IN_SCREEN を使用すると、FLAG_FULLSCREEN を有効にしたときに利用可能だった画面領域と同じ画面領域を使用するようにアクティビティ レイアウトを設定できます。これにより、ステータスバーの表示 / 非表示の切り替えがあっても、コンテンツのサイズを変更せずに維持できます。

ステータスバーを非表示にする(Android 4.1 以降)

Android 4.1(API レベル 16)以降の場合、setSystemUiVisibility() を使用することで、ステータスバーを非表示にできます。setSystemUiVisibility() は、個々のビューレベルで UI フラグをセットします。各設定はウィンドウ レベルに集約されます。setSystemUiVisibility() を使用して UI フラグをセットした場合、WindowManager フラグを使用した場合よりも、システムバーを詳細に制御できます。ステータスバーを非表示にするスニペットを以下に示します。

Kotlin

    // Hide the status bar.
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
    // Remember that you should never show the action bar if the
    // status bar is hidden, so hide that too if necessary.
    actionBar?.hide()
    

Java

    View decorView = getWindow().getDecorView();
    // Hide the status bar.
    int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
    decorView.setSystemUiVisibility(uiOptions);
    // Remember that you should never show the action bar if the
    // status bar is hidden, so hide that too if necessary.
    ActionBar actionBar = getActionBar();
    actionBar.hide();
    

注:

  • アクティビティを離れる操作をした場合など、UI フラグがクリアされた後、バーをもう一度非表示にしたい場合は、フラグをもう一度セットする必要があります。UI の表示設定変更をリッスンし、それに応答できるようにアプリを設計する方法については、UI の表示設定変更に応答するをご覧ください。
  • UI フラグをセットする場所によって違いが生じます。アクティビティの onCreate() メソッド内でシステムバーを非表示にした場合、ユーザーがホームボタンを押すと、システムバーが再表示されます。この場合、ユーザーがアクティビティを再度起動しても、onCreate() は呼び出されないため、システムバーは表示されたままになります。ユーザーがアクティビティの起動 / 終了を操作したときにシステム UI の表示設定変更を保持したい場合は、onResume()onWindowFocusChanged() 内で UI フラグをセットしてください。
  • setSystemUiVisibility() メソッドが効果を持つのは、呼び出し元のビューが表示されている場合に限られます。
  • ビューから離れると、setSystemUiVisibility() を使用してセットしたフラグはクリアされます。

コンテンツをステータスバーの背後に表示する

Android 4.1 以降の場合、アプリのコンテンツをステータスバーの背後に表示するように設定することで、ステータスバーの表示 / 非表示の切り替えがあっても、コンテンツのサイズを変更せずに維持できます。そのためには、SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN を使用します。また、SYSTEM_UI_FLAG_LAYOUT_STABLE を使用して、アプリが安定したレイアウトを維持できるようにすることをおすすめします。

このアプローチを使用する場合、アプリの UI の重要な部分(マップアプリのビルトイン コントロールなど)がシステムバーによって覆われないように注意する必要があります。このような部分が覆われると、アプリが使用できなくなる可能性があります。ほとんどの場合、true に設定した android:fitsSystemWindows 属性を XML レイアウト ファイルに追加することで対応できます。これにより、親 ViewGroup のパディングが調整され、システム ウィンドウ用のスペースが確保されます。ほとんどのアプリにおいて、この対応で十分です。

ただし、場合によっては、アプリにとって最適なレイアウトを実現するために、デフォルト パディングの変更が必要になります。システムバー(ウィンドウの「コンテンツ インセット」と呼ばれるスペースを占有)に対するコンテンツのレイアウトを直接操作するには、fitSystemWindows(Rect insets) をオーバーライドします。fitSystemWindows() メソッドは、ウィンドウのコンテンツ インセットが変更されたときにビュー階層によって呼び出されます。このメソッドにより、ウィンドウは、コンテンツ インセットの変更に応じてコンテンツを調整できます。このメソッドをオーバーライドすることにより、必要に応じてインセット(ならびに、その結果としてアプリのレイアウト)を処理できます。