setSystemUiVisibility (SYSTEM UI Flag LAYOUT скрыть навигацию) не работает

я боролся с 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 вы звоните из любой эффект? Я предполагаю, что документация (Сюрприз-сюрприз) здесь несколько отсутствует. Кто-нибудь знает, что на самом деле происходит?

4 ответов


Хм, видимо, я дублировать свой вопрос! но в любом случае я нашел ответ: прочитав исходный код - который часто является единственным способом узнать вещи в Android-land - я обнаружил следующий недокументированный факт:

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

enter image description here


вы уверены, что взаимодействие с пользователем не происходит? т. е. эмуляция касания, которое заставляет элементы управления мгновенно появляться?

С docs:

SYSTEM_UI_FLAG_HIDE_NAVIGATION: существует ограничение: поскольку навигационные элементы управления настолько важны,наименьшее взаимодействие с пользователем приведет к их немедленному появлению. Когда это происходит, как этот флаг и SYSTEM_UI_FLAG_FULLSCREEN будет очищен автоматически, так что оба элемента появятся снова в то же время время.

на боковой ноте я заметил проблемы с представлением, не изменяющимся при некоторых обстоятельствах даже с помощью видеоплеера в JB. Я думаю, что это (или была) ошибка.