Как скрыть панели состояния и навигации после первого касания?

Я использовал флаги SYSTEM_UI_FLAG_FULLSCREEN и SYSTEM_UI_FLAG_HIDE_NAVIGATION, чтобы скрыть и показать панели состояния и навигации. Они работают правильно. Я скрываю их, когда начинается действие, и я хочу снова показать их при касании. Android автоматически показывает их при первом касании (это первое касание не передается моему приложению). Я думаю использовать sendMessageDelayed(), чтобы скрыть обе полосы через определенное время. Как я могу использовать это событие первого касания?


person Prudhvi    schedule 25.08.2015    source источник


Ответы (2)


Я получил это, используя View.OnSystemUiVisibilityChangeListener. Я только что использовал Handler.sendMessageDelayed внутри условия if, когда видны и панель состояния, и панель навигации. См. приведенную ниже реализацию для ясности.

Источник : Реагирование на изменения видимости пользовательского интерфейса

View decorView = getActivity().getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {@Override
    public void onSystemUiVisibilityChange(int visibility) {
        if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
            // TODO: The system bars are visible. Make any desired
            Message msg = mHandler.obtainMessage(HIDE_STATUSBAR); //Implement your hide functionality accordingly                
            mHandler.sendMessageDelayed(msg, 3000);
        } else {
            // TODO: The system bars are NOT visible. Make any desired

            }
        }
    }
});

Недостатком этого подхода является то, что ваше приложение не может использовать событие первого касания. Я думаю, вам нужно использовать другие подходы, такие как WindowManager.LayoutParams или Полноэкранный режим с эффектом погружения в этом случае.

person Prudhvi    schedule 26.08.2015
comment
этот подход отлично работает, чтобы скрыть полосы, но когда отображается программная клавиатура, это происходит с рывком ... есть идеи, что вызывает это? - person Anupriya; 22.07.2019
comment
Не уверен, что вызывает мерцание, но попробуйте поиграть с этим атрибутом android:windowSoftInputMode - person Prudhvi; 22.07.2019

-Если вы хотите скрыть панель навигации, вы столкнетесь с проблемой первого касания, и ваше приложение ничего не сможет с этим сделать.

-Если вы хотите, вы можете использовать postDelayed(), чтобы скрыть полосы через определенное время, вот что я сделал:

Runnable navHider = new Runnable() {
    @Override
    public void run() {
        Log.e("HIDING", "hide");
        hideSystemUi();
    }

/** Hides StatusBar and NavigationBar */
private void hideSystemUi() {
    if (isLandscape()) {
        // Set flags for hiding status bar and navigation bar
        View decorView = ((Activity) context).getWindow().getDecorView();
         // Hide the status bar.
         int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
         | View.SYSTEM_UI_FLAG_FULLSCREEN
         | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
         | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
         | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
        int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
        decorView.setSystemUiVisibility(uiOptions);

    }
}

private void setVisibilityChangeListener() {
    View decorView = ((Activity) context).getWindow().getDecorView();
    decorView
            .setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
                @Override
                public void onSystemUiVisibilityChange(int visibility) {
                    // Note that system bars will only be "visible" if none
                    // of the
                    // LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are
                    // set.
                    if (isLandscape()) {
                        if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                            getHandler().postDelayed(navHider,
                                    UI_VISIBILITY_TIME);
                        }
                    }
                }
            });
}

Что мы делаем здесь:

- Во-первых, navHider — это объект Runnable, который скрывает системный интерфейс.

- Во-вторых, метод hideSystemUi устанавливает флаги параметров пользовательского интерфейса для скрытия строки состояния и панели навигации (обратите внимание, что мы также используем флаг LAYOUT_STABLE, чтобы содержимое отображалось за строкой состояния и панелями навигации, и нам не нужно было изменять размер содержимого.)

- В-третьих, мы используем systemUIVisibilityChangeListener, так что после того, как пользователь взаимодействует с экраном и отображаются панели состояния и навигации, мы используем postDelayed(), где время UIVisibility — это время, которое вы хотите подождать, прежде чем мы скроем статус и навигацию. бары

Вы также можете показать/скрыть строку состояния при каждом касании (или нажатии кнопки и т. д.). Мы можем сделать это только для строки состояния, но не для панели навигации:

/** Hides StatusBar and NavigationBar */
private void hideSystemUi() {
    if (isLandscape()) {
        // Set flags for hiding status bar and navigation bar
        View decorView = ((Activity) context).getWindow().getDecorView();
        // // Hide the status bar.
        int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
        decorView.setSystemUiVisibility(uiOptions);

        Window window = ((Activity) context).getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
        ((Activity) context).getActionBar().hide();
        isShowing = false;
    }
}

private void showSystemUi() {
    View decorView = ((Activity) context).getWindow().getDecorView();
    Window window = ((Activity) context).getWindow();
    decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
    ((Activity) context).getActionBar().show();
    isShowing = true;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_UP) {
        if (isShowing) {
            Log.e("onInterceptTouchEvent", "Hiding System UI");
            hideSystemUi();
        } else {
            Log.e("onInterceptTouchEvent", "Showing System UI");
            showSystemUi();
        }
    }
    return super.onInterceptTouchEvent(event);

}

Обратите внимание, что в этих двух методах: hideSystemUI() и showSystemUI(), чтобы избежать раздражающего «события первого касания», мы используем старые флаги до 4.0 для скрытия строки состояния.

Я использую этот код в своем ViewPager (который я использую для отображения изображений), поэтому я могу переопределить метод onInterceptTouchEvent(). Здесь я проверяю, отображается ли система или нет, с помощью простого логического значения. Также вам нужно использовать MotionEvent.ACTION_UP, это позволит вам прокручивать ViewPager без случайного отображения/скрытия строки состояния, чтобы вы могли прокручивать в полноэкранном режиме.

Что вы можете сделать, так это создать собственный макет (скажем, RelativeLayout), который расширяет ViewGroup, и вы можете перезаписать onInterceptTouchEvent и реализовать эту реализацию. Событие касания будет работать только на этом CustomRelativeLayout, поэтому, если вы хотите, чтобы оно работало на всей активности, просто сделайте CustomRelativeLayout базовым макетом с атрибутами match_parent для высоты/ширины.

Вот информация для отображения и скрытия статусных и навигационных панелей. https://developer.android.com/training/system-ui/status.html https://developer.android.com/training/system-ui/navigation.html

А это ссылка для управления сенсорными событиями. https://developer.android.com/training/gestures/viewgroup.html

person risto    schedule 25.08.2015