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

81

Я хочу постоянно скрывать панель навигации в своей деятельности (а не в пользовательском интерфейсе всей системы). теперь я использую этот кусок кода

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

Он скрывает панель, но когда пользователь касается экрана, она снова отображается. есть ли способ скрыть это навсегда до активности onStop();

Суджит Манджавана
источник
Здесь, по этой официальной ссылке Google / Android, изложено много хороших и конкретных деталей: Включить полноэкранный режим .
Крис Спрэг,
Флаг автоматически сбрасывается, когда пользователь касается экрана в соответствии с документацией. Вы должны внести изменения в свой дизайн пользовательского интерфейса, чтобы все время скрывать панель навигации.
user1154390

Ответы:

118

Фрагменты:

FullScreenFragment.java

HideNavigationBarComponent.java


Это для Android 4.4+

Попробуйте иммерсивный режим https://developer.android.com/training/system-ui/immersive.html

Быстрый фрагмент (для класса Activity ):

private int currentApiVersion;

@Override
@SuppressLint("NewApi")
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    currentApiVersion = android.os.Build.VERSION.SDK_INT;

    final int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_FULLSCREEN
        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;

    // This work only for android 4.4+
    if(currentApiVersion >= Build.VERSION_CODES.KITKAT)
    {

        getWindow().getDecorView().setSystemUiVisibility(flags);

        // Code below is to handle presses of Volume up or Volume down.
        // Without this, after pressing volume buttons, the navigation bar will
        // show up and won't hide
        final View decorView = getWindow().getDecorView();
        decorView
            .setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener()
            {

                @Override
                public void onSystemUiVisibilityChange(int visibility)
                {
                    if((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0)
                    {
                        decorView.setSystemUiVisibility(flags);
                    }
                }
            });
    }

}


@SuppressLint("NewApi")
@Override
public void onWindowFocusChanged(boolean hasFocus)
{
    super.onWindowFocusChanged(hasFocus);
    if(currentApiVersion >= Build.VERSION_CODES.KITKAT && hasFocus)
    {
        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_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }
}

Если при нажатии кнопки увеличения или уменьшения громкости возникают проблемы, отображается панель навигации. Я добавил код в onCreateсм. SetOnSystemUiVisibilityChangeListener

Вот еще один связанный с этим вопрос:

Навигация в режиме погружения становится липкой после нажатия кнопки громкости или минимизации-восстановления

Давид Дрозд
источник
4
Когда пользователь проводит пальцем вверх / вниз по экрану, полупрозрачные панели навигации временно появляются, а затем снова скрываются. МОЖНО ЛИ ЭТО СКРЫТЬ?
Finder
@KarthickRamu Я нашел способ, просто посмотрите на мой ответ :)
Мухаммед Рефаат
1
@MuhammedRefaat Для вашей подсказки необходимо устройство с root-доступом :(
Finder
1
@DawidDrozd Спасибо, но у меня проблема. Корневой макет моей активности - RelativeLayout, и у него есть дочернее представление, для которого установлено android: layout_alignParentBottom = "true", панель навигации исчезает, но дочернее представление не перемещается к нижнему краю экрана, как если бы панель навигации была невидимой, а не исчезла, не могли бы вы помочь?
Джек
1
Если вы хотите использовать пространство, которое занимала панель навигации, вам нужно удалить все вхождения этого android:fitsSystemWindows="true"из ваших представлений. Android Studio включает этот атрибут при создании некоторых макетов. См. Stackoverflow.com/a/42501330/650894
Джо Лапп
65

Сделай это.

public void FullScreencall() {
    if(Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
        View v = this.getWindow().getDecorView();
        v.setSystemUiVisibility(View.GONE);
    } else if(Build.VERSION.SDK_INT >= 19) {
        //for new api versions.
        View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        decorView.setSystemUiVisibility(uiOptions);
    }
}

Это работает на 100%, и вы можете сделать то же самое для более низких версий API, даже если это поздний ответ, я надеюсь, что это поможет кому-то другому.

Если вы хотите, чтобы это было постоянным, просто вызовите FullscreenCall()внутри своего onResume()метода.

Эвиш Верма
источник
2
Я рекомендую взглянуть на developer.android.com/training/system-ui/immersive.html , где объясняется, что ваш метод просто скрывает панель до тех пор, пока не произойдет взаимодействие, и снова вскоре после завершения взаимодействия.
Брошенная тележка
Большое вам спасибо - вот и все! : D: +1
Кристофер Сток
7

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

  getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

Это называется иммерсивным режимом. Вы можете посмотреть официальную документацию, чтобы узнать о других возможностях.

Харша Вардхан
источник
Я получаю сообщение об ошибке (не могу найти символ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);) `` @Override protected void onStart () {getWindow (). GetDecorView (). SetSystemUiVisibility (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION_STIM_SYSTEM) super.onStart (); } `` `
Билал Якуб
4

Согласно сайту разработчика Android

Я думаю, вы не можете (насколько я знаю) скрыть панель навигации навсегда.

Однако вы можете сделать одну уловку. Заметьте, это уловка.

Когда navigation barпоявляется, когда пользователь касается экрана. Немедленно снова спрячьте это. Это весело.

Проверить это .

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

// If we are now visible, schedule a timer for us to go invisible.
if (visible) {
    Handler h = getHandler();
    if (h != null) {
        h.removeCallbacks(mNavHider);
        if (!mMenusOpen && !mPaused) {
            // If the menus are open or play is paused, we will not auto-hide.
            h.postDelayed(mNavHider, 1500);
        }
    }
}

// Set the new desired visibility.
setSystemUiVisibility(newVis);
mTitleView.setVisibility(visible ? VISIBLE : INVISIBLE);
mPlayButton.setVisibility(visible ? VISIBLE : INVISIBLE);
mSeekView.setVisibility(visible ? VISIBLE : INVISIBLE);
}

См. Для получения дополнительной информации об этом ..

Скрыть системную панель в планшетах

Сандип Р
источник
3

Использование: -

view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

В планшетах под управлением Android 4+ скрыть панель системы / навигации невозможно.

Из документации :

SYSTEM_UI_FLAG_HIDE_NAVIGATION - это новый флаг, который запрашивает полное скрытие панели навигации. Имейте в виду, что это работает только для панели навигации, используемой некоторыми телефонами (она не скрывает системную панель на планшетах).

Намрата
источник
2

Это мое решение:

Сначала определите логическое значение, которое указывает, отображается ли панель навигации или нет.

boolean navigationBarVisibility = true //because it's visible when activity is created

Второй метод создания, скрывающий панель навигации.

private void setNavigationBarVisibility(boolean visibility){
    if(visibility){
        View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN;
        decorView.setSystemUiVisibility(uiOptions);
        navigationBarVisibility = false;
    }

    else
        navigationBarVisibility = true;
}

По умолчанию, если вы щелкнете действие после скрытия панели навигации, панель навигации будет видна. Итак, у нас есть состояние, если оно видно, мы его скроем.

Теперь установите OnClickListener на свое представление. Я использую Surfaceview, поэтому для меня:

    playerSurface.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            setNavigationBarVisibility(navigationBarVisibility);
        }
    });

Также мы должны вызывать этот метод при запуске активности. Потому что мы хотим скрыть это вначале.

        setNavigationBarVisibility(navigationBarVisibility);
PeerNet
источник
2

Это проблема безопасности: https://stackoverflow.com/a/12605313/1303691

поэтому невозможно навсегда скрыть навигацию на планшете одним единственным вызовом в начале создания представления. Он будет скрыт, но всплывет при касании экрана. Таким образом, всего лишь второе прикосновение к экрану может вызвать событие onClickEvent в макете. Поэтому вам нужно перехватить этот вызов, но я еще не успел это сделать, я обновлю свой ответ, когда узнаю об этом. Или вы уже ответили?

швейцарский кодировщик
источник
1

Я думаю, что код удара поможет вам, и добавьте этот код перед setContentView ()

getWindow().setFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

Добавьте этот код за setContentView () getWindow (). GetDecorView (). SetSystemUiVisibility (View.SYSTEM_UI_FLAG_LOW_PROFILE);

Цинфэй песня
источник
1
Поле требует API уровня 21+
zackygaurav
1

В других ответах в основном используются флаги для setSystemUiVisibility()метода View. Однако этот API устарел с Android 11. Дополнительные сведения см. В моей статье об изменении видимости пользовательского интерфейса системы. В статье также объясняется, как правильно обрабатывать вырезки или как прислушиваться к изменениям видимости.

Вот фрагменты кода для отображения / скрытия системных панелей с новым API, а также устаревшим для обратной совместимости:

/**
 * Hides the system bars and makes the Activity "fullscreen". If this should be the default
 * state it should be called from [Activity.onWindowFocusChanged] if hasFocus is true.
 * It is also recommended to take care of cutout areas. The default behavior is that the app shows
 * in the cutout area in portrait mode if not in fullscreen mode. This can cause "jumping" if the
 * user swipes a system bar to show it. It is recommended to set [WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER],
 * call [showBelowCutout] from [Activity.onCreate]
 * (see [Android Developers article about cutouts](https://developer.android.com/guide/topics/display-cutout#never_render_content_in_the_display_cutout_area)).
 * @see showSystemUI
 * @see addSystemUIVisibilityListener
 */
fun Activity.hideSystemUI() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        window.insetsController?.let {
            // Default behavior is that if navigation bar is hidden, the system will "steal" touches
            // and show it again upon user's touch. We just want the user to be able to show the
            // navigation bar by swipe, touches are handled by custom code -> change system bar behavior.
            // Alternative to deprecated SYSTEM_UI_FLAG_IMMERSIVE.
            it.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
            // make navigation bar translucent (alternative to deprecated
            // WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
            // - do this already in hideSystemUI() so that the bar
            // is translucent if user swipes it up
            window.navigationBarColor = getColor(R.color.internal_black_semitransparent_light)
            // Finally, hide the system bars, alternative to View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            // and SYSTEM_UI_FLAG_FULLSCREEN.
            it.hide(WindowInsets.Type.systemBars())
        }
    } else {
        // Enables regular immersive mode.
        // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
        // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        @Suppress("DEPRECATION")
        window.decorView.systemUiVisibility = (
                // Do not let system steal touches for showing the navigation bar
                View.SYSTEM_UI_FLAG_IMMERSIVE
                        // Hide the nav bar and status bar
                        or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        or View.SYSTEM_UI_FLAG_FULLSCREEN
                        // Keep the app content behind the bars even if user swipes them up
                        or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
        // make navbar translucent - do this already in hideSystemUI() so that the bar
        // is translucent if user swipes it up
        @Suppress("DEPRECATION")
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
    }
}

/**
 * Shows the system bars and returns back from fullscreen.
 * @see hideSystemUI
 * @see addSystemUIVisibilityListener
 */
fun Activity.showSystemUI() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        // show app content in fullscreen, i. e. behind the bars when they are shown (alternative to
        // deprecated View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION and View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
        window.setDecorFitsSystemWindows(false)
        // finally, show the system bars
        window.insetsController?.show(WindowInsets.Type.systemBars())
    } else {
        // Shows the system bars by removing all the flags
        // except for the ones that make the content appear under the system bars.
        @Suppress("DEPRECATION")
        window.decorView.systemUiVisibility = (
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
    }
}
Милош Черниловский
источник
Я пробовал ваши коды с флагом BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE на эмуляторе, но панель навигации всплывает и продолжает отображаться, когда я касаюсь экрана. Есть идеи, что еще я должен установить, чтобы получить липкую функциональность на Android 11?
Angel Koh
@AngelKoh Вы должны вызвать hideSystemUI () вручную, если хотите скрыть его. Проверьте статью, упомянутую в моем ответе, она содержит все эти детали. Прикрепленный режим означает, что полосы будут прозрачными, если пользователь проведет их вверх, и приложение также получит события касания (см. Developer.android.com/training/system-ui/… ).
Милош Черниловский
да вызывается hideSystemUI (), и пользовательский интерфейс скрывается в первый раз. однако, когда я затем касаюсь экрана, панель навигации выскакивает и остается отображаемой.
Angel Koh
Цель BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - предотвратить кражу касаний системой и отображение полос. Поэтому я не уверен, что могло вызвать это, не видя / не отлаживая реальное приложение.
Милош Черниловский,
0

Попробуй это:

View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
          | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
Рашад
источник
НЕТ, это даст мне тот же результат
Суджит Манджавана
0

Думаю, этот код решит вашу проблему. Скопируйте и вставьте этот код в свой MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {                          
    super.onCreate(savedInstanceState);

    View decorView = getWindow().getDecorView();
    decorView.setOnSystemUiVisibilityChangeListener
    (new View.OnSystemUiVisibilityChangeListener() {
        @Override
        public void onSystemUiVisibilityChange(int visibility) {

            if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                hideNavigationBar();
            } 
        }
    });
}



private void hideNavigationBar() {
   getWindow().getDecorView().setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}

Он будет работать на Android-10. Надеюсь, это поможет.

Сабарулла
источник