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, który na niektórych urządzeniach wykracza poza powierzchnię wyświetlacza. Dzięki temu zapewnia maksymalną wygodę korzystania, a jednocześnie zapewnia 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) i nowszym. Producenci urządzeń mogą też obsługiwać wycięcia w ekranie na urządzeniach z Androidem 8.1 lub starszym.

Ten dokument opisuje obsługę urządzeń z wycięciami, w tym jak korzystać z obszaru wycięcia – czyli prostokąta od krawędzi do krawędzi na powierzchni wyświetlacza, która zawiera wycięcie.

Obraz przedstawiający przykład wycięcia na środku u góry ekranu
Rysunek 1. 1 Wycięcie w ekranie.

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

Jeśli nie chcesz, aby treść Twojej treści pokrywała się z wycięciem, wystarczy mieć pewność, że nie nakłada się ona na pasek stanu i pasek nawigacyjny. Jeśli renderujesz w obszarze wycięcia, użyj metody WindowInsetsCompat.getDisplayCutout(), aby pobrać obiekt DisplayCutout, który zawiera bezpieczne wstawki i ramkę ograniczającą dla każdego wycięcia. Te interfejsy API pozwalają sprawdzić, czy Twoje treści nie nakładają się na wycięcie i w razie potrzeby można je zmienić.

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

Tryb wycięcia możesz ustawić automatycznie lub ustawiając styl w aktywności. Ten przykład określa styl, który ma zostać zastosowany do aktywności atrybut LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES.

<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

Domyślnie w trybie pionowym bez ustawionych specjalnych flag rozmiar paska stanu na urządzeniu z wycięciem jest skalowany co najmniej do wysokości wycięcia, a treści wyświetlają się w obszarze poniżej. W trybie poziomym lub pełnoekranowym okno aplikacji jest otoczone czarnymi pasami, przez co treści nie wyświetlają się w obszarze wycięcia.

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

W przypadku niektórych treści, np. filmów, zdjęć, map i gier, renderowanie w obszarze wycinania może być świetnym sposobem na zwiększenie atrakcyjności i wyjątkowe wrażenia użytkowników. W trybie LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES treści rozszerzają się do obszaru wycięcia na krótszej krawędzi wyświetlacza zarówno w orientacji pionowej, jak 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 obszar wycięcia.

Ten obraz to przykład obrazu 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 to przykład obrazu LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES na urządzeniu 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, zarówno w orientacji pionowej, jak i poziomej, rozszerza się pod wycięcia na krótszej krawędzi wyświetlacza, niezależnie od tego, czy okno ukrywa paski systemowe.

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

W polu LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER okno nie może się nigdy nakładać na obszar wycięcia.

Oto przykład właściwości LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w orientacji pionowej:

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

Oto przykład funkcji LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w trybie poziomym:

Ilustracja pokazująca tryb LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w orientacji poziomej
Rysunek 6. Przykład elementu 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. Zadbaj o to, aby obszar wycięcia nie zasłaniał ważnych tekstów, elementów sterujących ani innych informacji.
  • W obszarze wycięcia nie umieszczaj ani nie rozszerzaj żadnych elementów interaktywnych, które wymagają precyzyjnego rozpoznawania dotyku. Czułość ekranu może być niższa w obszarze wycięcia.
  • Jeśli to możliwe, używaj parametru WindowInsetsCompat, aby pobrać wysokość paska stanu i określić odpowiednie dopełnienie, które chcesz zastosować do treści. Unikaj kodowania na stałe wysokości paska stanu, ponieważ może to doprowadzić do nakładania się lub obcinania treści.

    Obraz pokazujący treść wyciętą u góry w celu niewłaściwej konfiguracji wkładek
    Rysunek 7. Aby unikać nakładania się lub obcinania treści, użyj właściwości WindowInsetsCompat.
  • View.getLocationInWindow() pozwala określić, ile przestrzeni okien używa aplikacja. Nie zakładaj, że aplikacja korzysta z całego okna, ani nie używaj View.getLocationOnScreen().

  • Jeśli aplikacja musi przejść do trybu pojemnego lub z niego wyjść, użyj trybów shortEdges lub never. Domyślne działanie wycięcia może spowodować, że treści w aplikacji będą renderowane w tym obszarze, gdy widoczne są paski systemowe, ale nie w trybie pojemnym. W efekcie treść przesuwa się w górę i w dół podczas przechodzenia, jak widać w 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ół podczas przejść.
  • W trybie pojemnym zachowaj ostrożność, używając współrzędnych okna i ekranu, ponieważ aplikacja nie wykorzystuje całego ekranu z wykorzystaniem poziomych pasów. Z powodu skrzyni liter współrzędne punktu początkowego ekranu nie są takie same jak współrzędne początku okna. W razie potrzeby możesz przekształcić współrzędne ekranu na współrzędne widoku za pomocą funkcji getLocationOnScreen(). Na ilustracji poniżej przedstawiono różnice współrzędnych w przypadku treści z czarnymi pasami:

    Obraz pokazujący współrzędne okna i ekranu, gdy treść jest otoczona pasami.
    Rysunek 9. Współrzędne okna i ekranu, gdy treść jest otoczona czarnymi pasami.
  • Podczas obsługi funkcji MotionEvent użyj MotionEvent.getX() i MotionEvent.getY(), aby uniknąć podobnych problemów ze współrzędnymi. Nie używaj MotionEvent.getRawX() ani MotionEvent.getRawY().

Testowanie renderowania treści

Przetestuj wszystkie ekrany i działalność aplikacji. W miarę możliwości przeprowadź testy na urządzeniach z różnymi typami wycięć. Jeśli nie masz urządzenia z wycięciem, możesz symulować typowe konfiguracje wycięcia na dowolnym urządzeniu lub emulatorze z Androidem 9 lub nowszym. Aby to zrobić:

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

    Obraz pokazujący, jak symulować wycięcie w ekranie w emulatorze
    Rysunek 10. Opcje programisty umożliwiające przetestowanie renderowania treści.

Dodatkowe materiały