Czarny pasek nawigacji u dołu ekranu nie jest łatwy do usunięcia w systemie Android. Jest częścią Androida od 3.0 jako zamiennik przycisków sprzętowych. Oto zdjęcie:
Jak mogę uzyskać rozmiar szerokości i wysokości tego elementu interfejsu użytkownika w pikselach?
Odpowiedzi:
Wypróbuj poniższy kod:
źródło
navigation_bar_height_landscape
dla wysokości paska nawigacji w trybie poziomym inavigation_bar_width
dla szerokości pionowego paska nawigacji). Musisz osobno dowiedzieć się, czy i gdzie faktycznie wyświetla się pasek nawigacji, np. Testując obecność fizycznego przycisku menu. Może znajdziesz inny sposób w kodzie źródłowym Androida na android.googlesource.com/platform/frameworks/base/+/…Rozmiar paska nawigacji uzyskuje, porównując rozmiar ekranu, który można wykorzystać w aplikacji, z rzeczywistym rozmiarem ekranu. Zakładam, że pasek nawigacji jest obecny, gdy rozmiar ekranu, z którego można korzystać przez aplikację, jest mniejszy niż rzeczywisty rozmiar ekranu. Następnie obliczam rozmiar paska nawigacyjnego. Ta metoda działa z API 14 i nowszymi.
AKTUALIZACJA
Aby znaleźć rozwiązanie uwzględniające wycięcia w ekranie, sprawdź odpowiedź Johna .
źródło
Wysokość paska nawigacji jest różna dla niektórych urządzeń, ale także dla niektórych orientacji. Najpierw musisz sprawdzić, czy urządzenie ma pasek nawigacyjny, następnie czy urządzenie jest tabletem czy nie tabletem (telefonem) i na końcu musisz spojrzeć na orientację urządzenia, aby uzyskać odpowiednią wysokość.
źródło
hasBackKey = false!
chociaż powinno być prawdą. Zamiast tego zadziałało:boolean navBarExists = getResources().getBoolean(getResources().getIdentifier("config_showNavigationBar", "bool", "android"));
Właściwie pasek nawigacji na tabletach (przynajmniej Nexus 7) ma inny rozmiar w orientacji pionowej i poziomej, więc ta funkcja powinna wyglądać następująco:
źródło
context.getResources().getConfiguration().orientation
Myślę, że lepsza odpowiedź jest tutaj, ponieważ pozwala również uzyskać równą wysokość wycięcia.
Weź swój główny widok i dodaj setOnApplyWindowInsetsListener (lub możesz nadpisać z niego onApplyWindowInsets) i pobierz z niego insets.getSystemWindowInsets.
W mojej aktywności kamery dodaję dopełnienie równe systemWindowInsetBottom do mojego dolnego układu. I wreszcie rozwiązuje problem z wycięciem.
z appcompat jest tak
bez appcompat, to:
źródło
setOnApplyWindowInsetsListener
zamiast tego użyć ? Jeśli tak to jak? i dlaczego rozróżniłeś LOLLIPOP od reszty?mam nadzieję, że to Ci pomoże
źródło
To jest mój kod, aby dodać paddingRight i paddingBottom do widoku, aby uniknąć paska nawigacji. Połączyłem tutaj niektóre odpowiedzi i stworzyłem specjalną klauzulę dotyczącą orientacji poziomej wraz z isInMultiWindowMode. Kluczem jest przeczytanie navigation_bar_height , ale także sprawdzenie config_showNavigationBar aby upewnić się, że faktycznie powinniśmy używać wysokości.
Żadne z poprzednich rozwiązań nie zadziałało. Od wersji Android 7.0 należy wziąć pod uwagę tryb wielu okien. To łamie implementacje porównujące display.realSize z display.size, ponieważ realSize podaje wymiary całego ekranu (oba podzielone okna), a rozmiar podaje tylko wymiary okna aplikacji. Ustawienie dopełnienia na tę różnicę spowoduje, że cały widok będzie wypełnieniem.
źródło
Wysokość dolnego paska nawigacji wynosi 48 dp (zarówno w trybie pionowym, jak i poziomym) i 42 dp, gdy pasek jest umieszczony pionowo.
źródło
Rozwiązanie zaproponowane przez Egidijusa i działa doskonale dla Build.VERSION.SDK_INT> = 17
Ale dostałem „NoSuchMethodException” podczas wykonywania poniższej instrukcji z Build.VERSION.SDK_INT <17 na moim urządzeniu:
Zmodyfikowałem metodę getRealScreenSize () dla takich przypadków:
źródło
Rozwiązałem ten problem na wszystkich urządzeniach (w tym Nexus 5, Samsung Galaxy Nexus 6 edge +, Samsung S10, Samsung Note II itp.). Myślę, że pomoże ci to rozwiązać problemy zależne od urządzenia.
Tutaj dodam dwa rodzaje kodów,
Kod Java (dla natywnego Androida):
I kod C # (dla Xamarin Forms / Android)
źródło
Display.getRealMetrics()
wymaga poziomu API 17screenOrientation
jest domyślnie,hasPermanentMenuKey
jestfalse
tylko wtedy, gdy nie jest obracany. [2] KiedyscreenOrientation
jest krajobraz, to wpada wdisplayMetrics.heightPixels != realDisplayMetrics.heightPixels)
inny. [3] KiedyscreenOrientation
jest portret,hasPermanentMenuKey
jestfalse
.Łącząc odpowiedź od @egis i innych - działa to dobrze na różnych urządzeniach, testowane na Pixel EMU, Samsung S6, Sony Z3, Nexus 4. Ten kod wykorzystuje wymiary wyświetlacza do testowania dostępności paska nawigacyjnego, a następnie używa rzeczywistego rozmiar paska nawigacyjnego systemu, jeśli jest obecny.
źródło
Jak uzyskać wysokość paska nawigacji i paska stanu. Ten kod działa dla mnie na niektórych urządzeniach Huawei i urządzeniach Samsung . Powyższe rozwiązanie Egis jest dobre, jednak na niektórych urządzeniach nadal jest niepoprawne. Więc poprawiłem to.
To jest kod, aby uzyskać wysokość paska stanu
Ta metoda zawsze zwraca wysokość paska nawigacji, nawet jeśli pasek nawigacji jest ukryty.
UWAGA: w Samsung A70 ta metoda zwraca wysokość paska stanu + wysokość paska nawigacji. Na innych urządzeniach (Huawei) zwraca tylko wysokość paska nawigacji i zwraca 0, gdy pasek nawigacji jest ukryty.
To jest kod do uzyskania wysokości paska nawigacji i paska stanu
źródło
Zrobiłem to, działa na każdym testowanym urządzeniu, a nawet na emulatorach:
źródło
Oto jak to rozwiązałem. Zrobiłem chowany dolny pasek, który wymagał wypełnienia w zależności od tego, czy był pasek nawigacyjny, czy nie (pojemnościowy, ekranowy lub po prostu przed lizakiem).
Widok
Utils.java
źródło
W moim przypadku, gdy chciałem mieć coś takiego:
Musiałem postępować zgodnie z tym samym, co sugerował @Mdlc, ale prawdopodobnie nieco prostszy (kierowanie tylko > = 21):
Działa również w krajobrazie:
Edytuj Powyższe rozwiązanie nie działa poprawnie w trybie wielu okien, gdzie użyteczny prostokąt nie jest mniejszy tylko ze względu na pasek nawigacji, ale także z powodu niestandardowego rozmiaru okna. Jedną z rzeczy, które zauważyłem, jest to, że w wielu oknach pasek nawigacji nie znajduje się nad aplikacją, więc nawet bez zmian w wypełnieniu DecorView mamy prawidłowe zachowanie:
Zwróć uwagę na różnicę między sposobem, w jaki pasek nawigacji znajduje się na dole aplikacji w tych scenariuszach. Na szczęście jest to łatwe do naprawienia. Możemy sprawdzić, czy aplikacja obsługuje wiele okien. Poniższy kod zawiera również część do obliczania i dostosowywania pozycji paska narzędzi (pełne rozwiązanie: https://stackoverflow.com/a/14213035/477790 )
Wynik w trybie wyskakującym Samsunga:
źródło
Testowany kod do pobierania wysokości paska nawigacji (w pikselach):
Testowany kod do pobierania wysokości paska stanu (w pikselach):
Konwersja pikseli na dp:
źródło
W przypadku Samsunga S8 żadna z powyższych metod nie dawała odpowiedniej wysokości paska nawigacji, więc użyłem androida dostawcy wysokości klawiatury KeyboardHeightProvider . I dało mi wzrost w wartościach ujemnych, a dla mojego pozycjonowania układu dostosowałem tę wartość w obliczeniach.
Oto
KeyboardHeightProvider.java
:popupwindow.xml
:Wykorzystanie w
MainActivity
Aby uzyskać dalszą pomoc, możesz rzucić okiem na zaawansowane wykorzystanie tego tutaj .
źródło
Jak sugerowano na przykład w wielu powyższych odpowiedziach
Samo pobranie wysokości paska nawigacji może nie wystarczyć. Musimy rozważyć, czy 1. istnieje pasek nawigacji, 2. czy jest na dole, czy po prawej czy lewej stronie, 3. czy aplikacja jest otwarta w trybie wielu okien.
Na szczęście możesz łatwo ominąć całe długie kodowanie, po prostu ustawiając
android:fitsSystemWindows="true"
układ główny. System Android automatycznie zajmie się dodaniem niezbędnego wypełnienia do układu głównego, aby upewnić się, że widoki podrzędne nie trafiają do paska nawigacji lub regionów paska stanu.Istnieje proste rozwiązanie jednokreskowe
lub programowo
możesz również uzyskać widok roota przez
Aby uzyskać więcej informacji na temat uzyskiwania widoku głównego, zobacz - https://stackoverflow.com/a/4488149/9640177
źródło