私はしばらくの間(ビデオプレーヤーの場合)ソフトナビゲーションボタンを非表示にしようとsetSystemUiVisibility()と戦ってきました。宣伝どおりに機能していないようです。これが私のコードで、目に見えるFrameLayout
の中にあります。
void setNavVisibility(boolean visible)
{
int newVis = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
if (!visible)
{
newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
setSystemUiVisibility(newVis);
}
SDKの例から少し変更:
void setNavVisibility(boolean visible) {
int newVis = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| SYSTEM_UI_FLAG_LAYOUT_STABLE;
if (!visible) {
newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN
| SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
呼び出されても何もしません。別のView
から呼び出したときにある程度の成功を収めましたが、ドキュメントには、呼び出し元のView
が効果があるとは記載されていませんか?私は、ドキュメントが(驚いたことに)ここにいくらか欠けていると思います。誰かが実際に何が起こっているのか知っていますか?
うーん、どうやら私は 私自身の質問を複製しました! しかしとにかく私は答えを見つけました:ソースコードを読んだ後-これはAndroidランドで物事を見つける唯一の方法であることがよくあります-私は次の文書化されていない事実を発見しました:
setSystemUiVisibility()は、呼び出し元のビューが表示されている場合にのみ有効です!
さらに:ナビゲーションバーを非表示にするには、setSystemUiVisibility()を呼び出すビューを表示したままにする必要があります。その人を文書化してくれてありがとう、本当に素晴らしい。
View.Java
の関連コードは次のとおりです。
void performCollectViewAttributes(AttachInfo attachInfo, int visibility) {
if ((visibility & VISIBILITY_MASK) == VISIBLE) {
if ((mViewFlags & KEEP_SCREEN_ON) == KEEP_SCREEN_ON) {
attachInfo.mKeepScreenOn = true;
}
attachInfo.mSystemUiVisibility |= mSystemUiVisibility;
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnSystemUiVisibilityChangeListener != null) {
attachInfo.mHasSystemUiListeners = true;
}
}
}
SetOnSystemUiVisibilityChangeListener()を使用して、ナビゲーションバーを非表示にするなど、このフルスクリーンモードを機能させます。
@Override
protected void onResume() {
if (Build.VERSION.SDK_INT >= 16) {
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(
new OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
getActionBar().show();
} else {
int mUIFlag = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
getWindow().getDecorView()
.setSystemUiVisibility(mUIFlag);
getActionBar().hide();
}
}
});
}
super.onResume();
}
Androidは、リスナー内でのみsetSystemUiVisibility()をトリガーするようです。
私はこれを以下のように実装しましたが、下部に空白のギャップがあります(スクリーンショットを参照)
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
}
}
}
ユーザーインタラクションが行われていないことを確認しますか?つまり、コントロールが即座に再表示されるタッチをエミュレートしますか?
docs から:
SYSTEM_UI_FLAG_HIDE_NAVIGATION
:制限があります。ナビゲーションコントロールは非常に重要であるため、ユーザーの操作が最も少ないと、すぐに再表示されます。これが発生すると、このフラグとSYSTEM_UI_FLAG_FULLSCREEN
の両方が自動的にクリアされるため、両方の要素が同時に再表示されます。
ちなみに、JBのストックビデオプレーヤーでも、状況によってはビューのサイズが変更されないという問題に気づきました。バグだと思います(またはバグでした)。