web-dev-qa-db-ja.com

setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)が機能しない

私はしばらくの間(ビデオプレーヤーの場合)ソフトナビゲーションボタンを非表示にしようと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が効果があるとは記載されていませんか?私は、ドキュメントが(驚いたことに)ここにいくらか欠けていると思います。誰かが実際に何が起こっているのか知っていますか?

9
Timmmm

うーん、どうやら私は 私自身の質問を複製しました! しかしとにかく私は答えを見つけました:ソースコードを読んだ後-これは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;
        }
    }
}
26
Timmmm

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()をトリガーするようです。

5
Duran Jayson

私はこれを以下のように実装しましたが、下部に空白のギャップがあります(スクリーンショットを参照)

@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
            );
        }
    }
}

enter image description here

4
Golan Shay

ユーザーインタラクションが行われていないことを確認しますか?つまり、コントロールが即座に再表示されるタッチをエミュレートしますか?

docs から:

SYSTEM_UI_FLAG_HIDE_NAVIGATION:制限があります。ナビゲーションコントロールは非常に重要であるため、ユーザーの操作が最も少ないと、すぐに再表示されます。これが発生すると、このフラグとSYSTEM_UI_FLAG_FULLSCREENの両方が自動的にクリアされるため、両方の要素が同時に再表示されます。

ちなみに、JBのストックビデオプレーヤーでも、状況によってはビューのサイズが変更されないという問題に気づきました。バグだと思います(またはバグでした)。

1
Oleg Vaskevich