最近ではこのモードを使うアプリも増えてきました。アプリを初めて起動した時、以下の様なメッセージが表示されるのを見たことがある人も多いでしょう。
メッセージにある様にシステムバー、ナビゲーションバーを表示するには画面の上端から下(または下端から上)へ向かってスワイプします。
設定するコードはだいたい以下の様なかんじになります。
if (Build.VERSION.SDK_INT >= 19) { Window window = getWindow(); View view = window.getDecorView(); view.setSystemUiVisibility( View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN); }
View#setSystemUiVisibility() で次の何れかのフラグを設定します。
- SYSTEM_UI_FLAG_IMMERSIVE
- SYSTEM_UI_FLAG_IMMERSIVE_STICKY
SYSTEM_UI_FLAG_IMMERSIVE は一度のユーザスワイプでImmersiveが解除されます。一方SYSTEM_UI_FLAG_IMMERSIVE_STICKYの方はスワイプで一時的にシステムバー、ナビゲーションバーが表示されますが、用が済めば再度非表示になります。
またこれらのフラグは SYSTEM_UI_FLAG_HIDE_NAVIGATION、SYSTEM_UI_FLAG_FULLSCREEN のどちらか、または両方と一緒に使った場合のみ効果があります。
さて上のコードでもそうですが、多くのサンプルコードでは DecoreView に対して setSystemUiVisivility() を設定しています。因みに DecoreView とは、ビューツリーの最上位にあり、Window に直接接続されているViewのことです。あまり馴染みがないかもしれません。
ダイアログを表示すると無効になってしまう
Immersiveモードを使ってみて残念だったのが、ちょっとしたことですぐにImmersiveモードから抜けてしまうことです。例えばダイアログを表示しただけで無効になってしまいます。ダイアログから抜けるのにBackキーを使うやり方もあるので、これはこれでアリかとも思いますが、ダイアログを終了しても元に戻らないのです。
上にも書いたようにImmersiveモードはWindowに対して設定されます。ダイアログはActivityとは別のWindowを持つので、ダイアログを表示した瞬間に上下のバーが表示されてしまいます。
これには回避方法があります。ダイアログがフォーカスを持たないようにしてやれば良いのです。DialogFragmentであれば以下のコードで回避できます。
onCreateDialog() で設定しても構いませんが、Windowに対する設定は onActivityCreated() でやるのが確実です。
またフォーカスを持たないようにするのでキーイベントは取得できません。(タッチイベントは取得可能です。) ダイアログ上でキーイベントが必要な場合(テキストを入力するとか)は別の方法を考えなくてはなりません。
Activity#onCreate() で設定すると一見うまくいっているように見えます。しかし一度ホーム画面を表示して、すぐにアプリに戻ってみて下さい。あれっ?Immersiveモードから抜けてしまいます。
ここはやはり Acrivity#onResume() で、表示直前に設定するのが確実ではないかと思います。
上にも書いたようにImmersiveモードはWindowに対して設定されます。ダイアログはActivityとは別のWindowを持つので、ダイアログを表示した瞬間に上下のバーが表示されてしまいます。
これには回避方法があります。ダイアログがフォーカスを持たないようにしてやれば良いのです。DialogFragmentであれば以下のコードで回避できます。
@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Dialog dialog = getDialog(); Window window = dialog.getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); }
onCreateDialog() で設定しても構いませんが、Windowに対する設定は onActivityCreated() でやるのが確実です。
またフォーカスを持たないようにするのでキーイベントは取得できません。(タッチイベントは取得可能です。) ダイアログ上でキーイベントが必要な場合(テキストを入力するとか)は別の方法を考えなくてはなりません。
どこで設定するか
最後にどこで設定すべきか検討してみます。Activity#onCreate() で設定すると一見うまくいっているように見えます。しかし一度ホーム画面を表示して、すぐにアプリに戻ってみて下さい。あれっ?Immersiveモードから抜けてしまいます。
ここはやはり Acrivity#onResume() で、表示直前に設定するのが確実ではないかと思います。
0 件のコメント :
コメントを投稿