Obsługa wycięć w ekranie

Wypróbuj sposób tworzenia wiadomości
Jetpack Compose to zalecany zestaw narzędzi UI na Androida. Dowiedz się, jak korzystać z wycięć w ekranie w narzędziu Compose

Wycięcie w ekranie to obszar na niektórych urządzeniach. który wykracza poza powierzchnię wyświetlacza. Umożliwia korzystanie z nowoczesnych rozwiązań a jednocześnie pozostawiono miejsce na ważne czujniki z przodu urządzenia.

Android obsługuje wycięcia w ekranie na urządzeniach z Androidem 9 (poziom interfejsu API 28) oraz wyższe. Producenci urządzeń mogą jednak stosować wycięcia w ekranie urządzeniach z Androidem 8.1 lub starszym.

W tym dokumencie opisujemy, jak wdrożyć obsługę urządzeń z wycięciami, m.in. jak pracować z obszarem wycięcia, czyli krawędzią od krawędzi do krawędzi. prostokąt z wycięciem.

Obraz przedstawiający przykład wycięcia na środku u góry ekranu
Rysunek 1. 1 Wyświetlacz wycięcie tekstu.

Wybierz, jak aplikacja ma obsługiwać wycięcia

Jeśli nie chcesz, aby treści nakładały się na obszar z wycięciem, wystarcza do tego, aby treść nie nakładała się na pasek stanu na pasku nawigacyjnym. Jeśli renderujesz w obszarze wycięcia, użyj WindowInsetsCompat.getDisplayCutout() aby pobrać obiekt DisplayCutout który zawiera bezpieczne wcięcia i ramkę ograniczającą dla każdego wycięcia. Dzięki tym interfejsom API aby sprawdzić, czy treść nie nakłada się na wycięcie, i w razie potrzeby zmienić jej położenie.

Możesz też określić, czy treść ma być rozmieszczona za wycięciem. layoutInDisplayCutoutMode Atrybut układu okna określa sposób rysowania treści w obszarze wycięcia. W polu layoutInDisplayCutoutMode możesz ustawić jedną z tych wartości:

  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT: gdy wycięcie w ekranie znajdzie się w na pasku systemu. W przeciwnym razie okno nie będzie nakładać się na wycięcie w ekranie. w przypadku Na przykład treści wyświetlane w trybie poziomym mogą mieć poziome pasy. Jeśli aplikacja jest kierowana na pakiet SDK 35, w przypadku zasobów nieswobodnych jest to interpretowane jako ALWAYS oknach.
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS: materiały mogą się zawsze rozszerzać na obszary wycięcia. Jeśli Twoja aplikacja jest kierowana Pakiet SDK 35 działa na urządzeniu z Androidem 15. To jedyny dozwolony tryb w przypadku nie pływających, aby zapewnić pełną widoczność.
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES: w obszarze wycięcia zarówno w orientacji pionowej, jak i poziomej. Przeciwwskazania dla pływających okien. Jeśli aplikacja jest kierowana na pakiet SDK 35, będzie to interpretowane jako ALWAYS dla okien niepływających.
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER: nigdy nie renderuje się w obszarze wycięcia. Jeśli Twoja aplikacja jest kierowana na pakiet SDK 35, interpretowane jako ALWAYS w przypadku okien niepływających.

Tryb wycięcia możesz ustawić automatycznie lub styl aktywności. Poniżej przykład definiuje styl, w którym zostanie zastosowana LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES do aktywności.

<style name="ActivityTheme">
  <item name="android:windowLayoutInDisplayCutoutMode">
    shortEdges <!-- default, shortEdges, or never -->
  </item>
</style>

W kolejnych sekcjach szczegółowo opisujemy różne tryby wycinania.

Domyślne zachowanie

Jeśli Twoja aplikacja jest kierowana na pakiet SDK 35 i działa na urządzeniu z Androidem 15, LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS to działanie domyślne. LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT jest interpretowany jako LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS dla okien niepływających.

W przeciwnym razie domyślna wartość to LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT.

Renderuj treść w obszarach z wycięciami w krótszych krawędziach

Jeśli Twoja aplikacja jest kierowana na pakiet SDK 35 i działa na urządzeniu z Androidem 15, Działanie LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES jest interpretowane jako LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS dla okien niepływających.

Dzięki funkcji LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES W każdym z tych miejsc materiały rozciąga się do obszaru wycięcia na krótszej krawędzi wyświetlacza w orientacji pionowej i poziomej, niezależnie od tego, czy paski systemowe są ukryte czy widoczne. Podczas korzystania z tego trybu upewnij się, że żadne ważne treści nie nakładają się na w obszarze wycięcia.

Ten obraz przedstawia przykładowy: LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES w przypadku urządzenia w orientacji pionowej:

Obraz pokazujący renderowanie treści w obszarze wycięcia w trybie pionowym
Rysunek 2. Renderowanie treści w obszarze wycięcia w trybie pionowym.

Ten obraz przedstawia przykładowy: LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES w przypadku urządzenia w orientacji poziomej:

Obraz pokazujący renderowanie treści w obszarze wycięcia w trybie poziomym
Rysunek 3. Renderowanie treści w obszarze wycięcia w trybie poziomym.

W tym trybie okno jest rozciągane pod wycięciami na krótszej krawędzi wyświetlacza. w orientacji pionowej i poziomej niezależnie od tego, czy okno ukrywa pasków systemowych.

Wycięcie w rogu uznaje się za tę, która znajduje się na krótszej krawędzi:

Obraz przedstawiający urządzenie z wycięciem narożnym
Rysunek 4. Urządzenie z wycięciem narożnym.

Nigdy nie renderuj treści w obszarze wycięcia w ekranie

Jeśli Twoja aplikacja jest kierowana na pakiet SDK 35 i działa na urządzeniu z Androidem 15, Działanie LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER jest interpretowane jako LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS dla okien niepływających.

Gdy używasz zasady LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER, okno nigdy nie może które nakładają się na obszar wycięcia.

Oto przykład elementu LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w języku: orientacja pionowa:

Obraz pokazujący LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w orientacji pionowej
Rysunek 5. Przykład LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w trybie pionowym.

Oto przykład elementu LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w języku: tryb poziomy:

Ilustracja pokazująca tryb LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w orientacji poziomej
Rysunek 6. Przykład LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w trybie poziomym.

Sprawdzone metody dotyczące obsługi wycięć w ekranie

Podczas pracy z wycięciami w ekranie weź pod uwagę te kwestie:

  • Zwróć uwagę na rozmieszczenie kluczowych elementów interfejsu. Nie pozwól, aby zasłaniają ważny tekst, elementy sterujące i inne informacje.
  • Nie umieszczaj ani nie rozszerzaj żadnych elementów interaktywnych, które wymagają precyzyjnego dotyku. do obszaru wycięcia. Czułość ekranu może być niższa i miejsca wycięcia.
  • W miarę możliwości używaj WindowInsetsCompat do pobierz wysokość paska stanu i określ odpowiednie dopełnienie do Twoich treści. Unikaj kodowania na stałe wysokości paska stanu, ponieważ może to prowadzić treści nakładających się lub odciętych.

    Obraz pokazujący treść wyciętą u góry w celu niewłaściwej konfiguracji wkładek
    Rysunek 7. WindowInsetsCompat – do unikaj nakładania się lub obcinania treści.
  • Użyj formatu View.getLocationInWindow() aby określić, ile przestrzeni okien używa aplikacja. Nie zakładaj, że aplikacja całe okno, a nie używaj go View.getLocationOnScreen()

  • Jeśli aplikacja wymaga, użyj trybów always, shortEdges lub never między trybem pojemnym. Domyślne działanie wycięcia może powodować treści w aplikacji, by były renderowane w obszarze wycięcia, a paski systemowe są obecny, ale nie w trybie pojemnym. Powoduje to przeniesienie treści wyżej i w dół podczas przejść, jak widać na przykładzie poniżej.

    Obraz pokazujący treść przesuwającą się w górę i w dół podczas przejść.
    Rysunek 8. Przykład treści przesuwających się w górę i w dół w czasie przejść.
  • W trybie pojemnym zachowaj ostrożność, używając współrzędnych okna i ekranu, ponieważ Aplikacja nie zajmuje całego ekranu, gdy korzystasz z formatu letterbox. Z powodu letterbox, współrzędne punktu początkowego ekranu nie są takie same od punktu początkowego okna. Możesz przekształcić współrzędne ekranu na współrzędne za pomocą funkcji getLocationOnScreen(). Następujący obraz pokazuje, czym różnią się współrzędne, gdy treść jest dodana do poziomych pasów:

    Obraz pokazujący współrzędne okna i ekranu, gdy treść jest otoczona pasami.
    Rysunek 9. gdy współrzędne okna i ekranu, jest wyświetlana na czarnych pasach.
  • Do obsługi atrybutu MotionEvent użyj funkcji MotionEvent.getX() i MotionEvent.getY(), których należy unikać z podobnymi współrzędnymi. Nie używaj MotionEvent.getRawX() lub MotionEvent.getRawY()

Testowanie renderowania treści

Przetestuj wszystkie ekrany i działalność aplikacji. Przetestuj na urządzeniach z różnymi typy wycięć, o ile to możliwe. Jeśli nie masz urządzenia z wycięciem, symuluj typowe konfiguracje wycięcia na dowolnym urządzeniu lub emulatorze z Androidem 9 lub wyższej, wykonując te czynności:

  1. Włącz Opcje programisty.
  2. Na ekranie Opcje programisty przewiń w dół do sekcji Rysunek. i wybierz Symuluj wyświetlacz z wycięciem.
  3. Wybierz typ wycięcia.

    Obraz pokazujący, jak symulować wycięcie w ekranie w emulatorze
    Rysunek 10. Opcje programisty, aby sprawdzić działanie podczas renderowania treści.

Dodatkowe materiały