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

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

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

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


person Sujith Manjavana    schedule 12.02.2014    source источник
comment
возможный дубликат навсегда скрыть панель навигации в действии   -  person Shiva    schedule 12.02.2014
comment
Много полезных и конкретных деталей изложено здесь, по этой официальной ссылке Google/Android: Включить полноэкранный режим.   -  person Chris Sprague    schedule 11.08.2019
comment
Флаг автоматически очищается, когда пользователь касается экрана в соответствии с документацией. Вы должны внести изменения в свой дизайн пользовательского интерфейса, чтобы постоянно скрывать панель навигации.   -  person user1154390    schedule 22.01.2020


Ответы (13)


Фрагменты:

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

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

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

person Dawid Drozd    schedule 03.04.2014
comment
Когда пользователь прокручивает верхнюю/нижнюю часть экрана, отображаются полупрозрачные панели навигации, которые временно появляются, а затем снова скрываются. МОЖНО ЛИ ЭТО ТОЖЕ СКРЫТЬ? - person Finder; 18.09.2014
comment
@KarthickRamu Я нашел способ, просто посмотри на мой ответ :) - person Muhammed Refaat; 24.09.2014
comment
@MuhammedRefaat Ваша подсказка требует рутированного устройства :( - person Finder; 25.09.2014
comment
да, извините за это :( - person Muhammed Refaat; 25.09.2014
comment
Я получаю это исключение: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.android.internal.widget.ActionBarContainer.setAlpha(float)' on a null object reference at com.android.internal.app.WindowDecorActionBar.doHide(WindowDecorActionBar.java:822) - person Shajeel Afzal; 24.08.2015
comment
Спасибо за gist, панель навигации скроется навсегда? И я думаю, мне нужно поместить всю логику моей деятельности во фрагмент и показать ее в действии? - person Shajeel Afzal; 26.08.2015
comment
@DawidDrozd Спасибо, но у меня проблема: мой корневой макет активности - RelativeLayout, и у него есть дочернее представление, для которого установлено android:layout_alignParentBottom=true, панель навигации исчезает, но дочернее представление не перемещается к нижнему краю экран, как будто панель навигации настроена на невидимую не пропала, не могли бы вы помочь? - person Jack; 21.10.2018
comment
@Jack Возможно, вам нужно перемерить весь вид, но не уверен. Попробуйте аннулировать, как здесь: stackoverflow.com/questions/6946478/ - person Dawid Drozd; 22.10.2018
comment
Если вы хотите использовать пространство, занимаемое панелью навигации, вы должны удалить все вхождения android:fitsSystemWindows="true" из своих представлений. Android Studio включает этот атрибут при создании некоторых макетов. См. stackoverflow.com/a/42501330/650894. - person Joe Lapp; 08.06.2019
comment
Хм, это работает, с одной оговоркой: когда в моем приложении я нажимаю любую кнопку, которая вызывает появление нового окна на экране («окно» — то есть DialogFrament, PopupWindow или просто окно списка выбора Spinner) — тогда панель навигации снова появляется и остается там до тех пор, пока соответствующее окно не будет закрыто. Любое лекарство от этого? - person Leszek; 18.09.2020
comment
Это работает, но я использовал только часть oncreate(){...}. Я не интегрировал функцию onWindowFocusChanged, и все работает отлично. - person Mimouni; 25.12.2020

Сделай это.

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().

person Evish Verma    schedule 06.01.2015
comment
Я рекомендую взглянуть на developer.android.com/training/system-ui/ immersive.html, в котором объясняется, что ваш метод просто скрывает панель до тех пор, пока не произойдет взаимодействие, и снова вскоре после завершения взаимодействия. - person Abandoned Cart; 07.04.2018

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

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

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

person Harsha Vardhan    schedule 21.09.2019
comment
Я получаю ошибку (не могу найти символ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);) ``` @Override protected void onStart() { getWindow(). супер.onStart(); }``` - person ; 12.12.2020

Согласно сайту разработчиков 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);
}

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

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

person Sandeep R    schedule 12.02.2014

Использовать:-

view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

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

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

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

person Namrata    schedule 12.02.2014

В других ответах в основном используются флаги для метода 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)
    }
}
person Miloš Černilovský    schedule 24.09.2020
comment
Я попробовал ваши коды с флагом BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE на эмуляторе, но панель навигации будет всплывать и отображаться, когда я касаюсь экрана. Есть идеи, что еще я должен установить, чтобы получить функциональность STICKY на Android 11? - person Angel Koh; 15.10.2020
comment
@AngelKoh Вы должны вызвать hideSystemUI() вручную, если хотите скрыть это. Проверьте статью, упомянутую в моем ответе, она содержит все эти детали. Прикрепленный режим означает, что панели будут прозрачными, если пользователь проведет их вверх, и приложение также будет получать события касания (см. developer.android.com/training/system-ui/). - person Miloš Černilovský; 15.10.2020
comment
да, вызывается hideSystemUI(), и пользовательский интерфейс был скрыт в первый раз. однако, когда я после этого прикасаюсь к экрану, панель навигации снова выскакивает и остается отображаемой. - person Angel Koh; 15.10.2020
comment
Цель BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE — предотвратить кражу касаний системой и отображение полос. Поэтому я не уверен, что могло вызвать это, не видя/отлаживая реальное приложение. - person Miloš Černilovský; 15.10.2020

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

Во-первых, определите логическое значение, указывающее, видна панель навигации или нет.

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 для вашего представления. Я использую представление поверхности, поэтому для меня:

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

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

        setNavigationBarVisibility(navigationBarVisibility);
person PeerNet    schedule 05.09.2017

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

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

person swisscoder    schedule 02.05.2014

Я думаю, что код удара поможет вам, и добавьте этот код перед 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);

person qingfei song    schedule 23.06.2017
comment
Поле требует уровня API 21+ - person zackygaurav; 21.07.2017

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

View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
          | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
person Rashad    schedule 12.02.2014
comment
НЕТ, это дает мне тот же результат - person Sujith Manjavana; 12.02.2014

Я думаю, что этот код решит вашу проблему. Скопируйте и вставьте этот код в свой 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. Я надеюсь, что это поможет.

person Sabarulla    schedule 02.05.2020

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

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        View decorView = getWindow().getDecorView();
        if(hasFocus){
            decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
                    View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
            );
        }
    }

Таким образом, вы можете скрыть кнопки навигации, не скрывая строку состояния.

person Shibl    schedule 12.06.2021

Попробуйте это для всех версий Android, включая Android 30(R).

Для получения дополнительной информации проверьте этот класс: https://github.com/fiftyonemoon/Rapid/blob/main/rapid/src/main/java/com/fom/rapid/app/UI.java

Показать/скрыть все системные панели:

 public void hideSystemUI(Window window) { //pass getWindow();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {

        window.getInsetsController().hide(WindowInsets.Type.systemBars());

    } else {

        View decorView = window.getDecorView();

        int uiVisibility = decorView.getSystemUiVisibility();

        uiVisibility |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
        uiVisibility |= View.SYSTEM_UI_FLAG_FULLSCREEN;
        uiVisibility |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            uiVisibility |= View.SYSTEM_UI_FLAG_IMMERSIVE;
            uiVisibility |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        }

        decorView.setSystemUiVisibility(uiVisibility);
    }
}


public void showSystemUI(Window window) { //pass getWindow();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {

        window.getInsetsController().show(WindowInsets.Type.systemBars());

    } else {
        View decorView = window.getDecorView();

        int uiVisibility = decorView.getSystemUiVisibility();

        uiVisibility &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
        uiVisibility &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
        uiVisibility &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            uiVisibility &= ~View.SYSTEM_UI_FLAG_IMMERSIVE;
            uiVisibility &= ~View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        }

        decorView.setSystemUiVisibility(uiVisibility);
    }
}
person hardkgosai    schedule 27.06.2021