Jak trwale ukryć pasek nawigacji w aktywności Androida?

81

Chcę na stałe ukryć pasek nawigacji w mojej aktywności (nie cały interfejs systemu). teraz używam tego fragmentu kodu

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

Ukrywa pasek, ale gdy użytkownik dotknie ekranu, pojawia się ponownie. czy istnieje sposób, aby ukryć to na stałe do czasu aktywności onStop();

Sujith Manjavana
źródło
Wiele dobrych i konkretnych szczegółów jest opisanych tutaj, w tym oficjalnym linku Google / Android: Włącz tryb pełnoekranowy .
Chris Sprague,
Flaga automatycznie kasowała się po dotknięciu ekranu przez użytkownika zgodnie z dokumentacją. Musisz wprowadzać zmiany w projekcie interfejsu użytkownika, aby cały czas ukrywać pasek nawigacji.
user1154390

Odpowiedzi:

118

Fragmenty:

FullScreenFragment.java

HideNavigationBarComponent.java


To dotyczy Androida 4.4+

Wypróbuj tryb immersyjny https://developer.android.com/training/system-ui/immersive.html

Krótki opis (dla klasy 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);
    }
}

Jeśli masz problemy po naciśnięciu przycisku zwiększania lub zmniejszania głośności, który pokazuje pasek nawigacji. Dodałem kod w onCreatepatrz setOnSystemUiVisibilityChangeListener

Oto inne powiązane pytanie:

Nawigacja w trybie immersyjnym staje się lepka po naciśnięciu głośności lub przywróceniu minimalizacji

Dawid Drozd
źródło
4
Gdy użytkownik przesunie górę / dół ekranu, tymczasowo pojawią się półprzezroczyste paski nawigacji, a następnie ponownie się ukryją. CZY MOŻNA TAKŻE UKRYĆ?
Finder
@KarthickRamu znalazłem sposób, spójrz tylko na moją odpowiedź :)
Muhammed Refaat
1
@MuhammedRefaat Twoja wskazówka wymaga zrootowanego urządzenia :(
Finder,
1
@DawidDrozd Dziękuję, ale mam problem, układ katalogu głównego mojej aktywności to RelativeLayout i ma widok potomny ustawiony na android: layout_alignParentBottom = "true", pasek nawigacji znika, ale widok podrzędny nie przesuwa się do dolnej krawędzi ekranu, jakby pasek nawigacji był ustawiony jako niewidoczny, a nie zniknął, czy możesz pomóc?
Jack
1
Jeśli chcesz wykorzystać miejsce zajmowane przez pasek nawigacji, musisz usunąć wszystkie wystąpienia android:fitsSystemWindows="true"z widoków. Android Studio zawiera ten atrybut podczas generowania niektórych układów. Zobacz stackoverflow.com/a/42501330/650894
Joe Lapp
65

Zrób to.

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

Działa to w 100% i możesz zrobić to samo dla niższych wersji API, nawet jeśli jest to późna odpowiedź, mam nadzieję, że pomoże to komuś innemu.

Jeśli chcesz, aby to było trwałe, po prostu zadzwoń FullscreenCall()do swojej onResume()metody.

Evish Verma
źródło
2
Polecam zajrzeć na developer.android.com/training/system-ui/immersive.html , gdzie wyjaśniono, że Twoja metoda po prostu ukrywa pasek do czasu interakcji i ponownie wkrótce po zakończeniu interakcji.
Opuszczony
Dziękuję bardzo - To się udało! : D: +1
Christopher Stock
7

Dla osób szukających prostszego rozwiązania myślę, że możesz mieć po prostu ten jeden wiersz kodu onStart()

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

Nazywa się to trybem immersyjnym. Możesz zajrzeć do oficjalnej dokumentacji pod kątem innych możliwości.

Harsha Vardhan
źródło
Otrzymuję błąd (nie mogę znaleźć symbolu View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);) `` @Override chronione void onStart () {getWindow (). GetDecorView (). SetSystemUiVisibility (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_IMYSTIC); super.onStart (); } ``
Bilal Yaqoob
4

Według witryny Android Developer

Myślę, że nie możesz (o ile wiem) ukryć paska nawigacji na stałe.

Możesz jednak zrobić jedną sztuczkę. To sztuczka, uwaga.

Właśnie wtedy, gdy navigation barpojawia się, gdy użytkownik dotyka ekranu. Natychmiast ukryj to ponownie. To zabawne.

Sprawdź to .

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

Zobacz to, aby uzyskać więcej informacji na ten temat.

Ukryj pasek systemowy w tabletach

Sandeep R
źródło
3

Posługiwać się:-

view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

Na tabletach z systemem Android 4+ nie można ukryć paska systemu / nawigacji.

Z dokumentacji :

SYSTEM_UI_FLAG_HIDE_NAVIGATION to nowa flaga, która żąda całkowitego ukrycia paska nawigacji. Należy pamiętać, że działa to tylko w przypadku paska nawigacji używanego przez niektóre telefony (nie ukrywa paska systemowego na tabletach).

Namrata
źródło
2

To moje rozwiązanie:

Najpierw zdefiniuj wartości logiczne, które wskazują, czy pasek nawigacji jest widoczny, czy nie.

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

Druga metoda tworzenia, która ukrywa pasek nawigacji.

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

Domyślnie, jeśli klikniesz na aktywność po ukryciu paska nawigacji, pasek nawigacji będzie widoczny. Więc mamy jego stan, jeśli jest widoczny, to ukryjemy.

Teraz ustaw OnClickListener na swój widok. Używam widoku powierzchni, więc dla mnie:

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

Musimy również wywołać tę metodę po uruchomieniu działania. Ponieważ chcemy to ukryć na początku.

        setNavigationBarVisibility(navigationBarVisibility);
PeerNet
źródło
2

To kwestia bezpieczeństwa: https://stackoverflow.com/a/12605313/1303691

dlatego nie można trwale ukryć Nawigacji na tablecie za pomocą jednego wywołania na początku tworzenia widoku. Będzie ukryty, ale wyskoczy po dotknięciu ekranu. Zatem już drugie dotknięcie ekranu może spowodować zdarzenie onClickEvent w układzie. Dlatego musisz przechwycić to połączenie, ale jeszcze mi się to nie udało, zaktualizuję odpowiedź, gdy się dowiem. Czy masz już odpowiedź?

swisscoder
źródło
1

Myślę, że kod blow pomoże ci i dodaj ten kod przed setContentView ()

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

Dodaj ten kod za setContentView () getWindow (). GetDecorView (). SetSystemUiVisibility (View.SYSTEM_UI_FLAG_LOW_PROFILE);

piosenka qingfei
źródło
1
Pole wymaga poziomu API 21+
zackygaurav
1

Inne odpowiedzi używają głównie flag dla setSystemUiVisibility()metody w View. Jednak ten interfejs API jest przestarzały od wersji Androida 11. Więcej informacji można znaleźć w moim artykule na temat modyfikowania widoczności interfejsu użytkownika systemu. Artykuł wyjaśnia również, jak prawidłowo obsługiwać wycięcia lub jak słuchać zmian widoczności.

Oto fragmenty kodu służące do pokazywania / ukrywania pasków systemowych z nowym interfejsem API, a także z wycofanym w celu zapewnienia zgodności z poprzednimi wersjami:

/**
 * 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)
    }
}
Miloš Černilovský
źródło
Wypróbowałem twoje kody z flagą BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE na emulatorze, ale pasek nawigacji wyskakuje i pozostanie wyświetlany, gdy dotknę ekranu. Masz pomysł, co jeszcze powinienem ustawić, aby uzyskać funkcjonalność STICKY w systemie Android 11?
Angel Koh
@AngelKoh Musisz ręcznie wywołać hideSystemUI (), jeśli chcesz to ukryć. Sprawdź artykuł wspomniany w mojej odpowiedzi, zawiera wszystkie te szczegóły. Tryb przyklejony oznacza, że ​​paski będą przezroczyste, jeśli użytkownik przesunie je w górę, a aplikacja otrzyma również zdarzenia dotykowe (patrz developer.android.com/training/system-ui/… ).
Miloš Černilovský
tak jest wywoływana funkcja hideSystemUI (), a interfejs użytkownika został ukryty za pierwszym razem. Jednak gdy później dotknę ekranu, pasek nawigacji wyskakuje z powrotem i pozostaje wyświetlony.
Angel Koh
Celem BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE jest zapobieganie kradzieży dotknięć systemu i wyświetlaniu pasków. Nie jestem więc pewien, co może to spowodować bez oglądania / debugowania prawdziwej aplikacji.
Miloš Černilovský
0

Spróbuj tego:

View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
          | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
Rashad
źródło
NIE, to daje mi ten sam wynik
Sujith Manjavana,
0

Myślę, że ten kod rozwiąże Twój problem. Skopiuj i wklej ten kod do pliku 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);
}

Będzie działać na Androidzie-10. Mam nadzieję, że to pomoże.

Sabarulla
źródło