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 oknie tworzenia wiadomości.

Wycięcie w ekranie to na niektórych urządzeniach obszar, który rozciąga się na powierzchnię wyświetlacza. Zapewnia on zaawansowane wrażenia od krawędzi do krawędzi, 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) lub nowszym. Producenci urządzeń mogą jednak również obsługiwać wycięcia w ekranie na urządzeniach z Androidem 8.1 lub starszym.

Ten dokument opisuje, jak wdrożyć obsługę urządzeń z wycięciem, w tym jak pracować z obszarem wycięcia, czyli prostokątem od krawędzi do krawędzi na powierzchni wyświetlacza, która zawiera wycięcie.

Ilustracja przedstawiająca przykład wycięcia w wyświetlaczu na środku u góry
Rysunek 1. 1 Wycięcie w ekranie.

Wybierz, jak aplikacja obsługuje obszary z wycięciem

Jeśli nie chcesz, aby treść nakładała się na obszar wycięcia, nie musisz zasłaniać treści paskami stanu i paskami 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. Te interfejsy API pozwalają sprawdzić, czy treści nie nakładają się na wycięcie, i w razie potrzeby zmienić ich położenie.

Możesz też ustalić, czy treść ma się znajdować za obszarem wycięcia. Atrybut układu okna layoutInDisplayCutoutMode określa sposób rysowania treści w obszarze wycięcia. Możesz ustawić layoutInDisplayCutoutMode na jedną z tych wartości:

Tryb wycinania możesz ustawić automatycznie lub przez określenie stylu w aktywności. W tym przykładzie zdefiniowano styl stosujący 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 poniższych sekcjach opisano bardziej szczegółowo 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 zmieniany na co najmniej wysokości wycięcia, a treść jest widoczna poniżej. W trybie poziomym lub pełnoekranowym okno aplikacji jest oparte na czarnych pasach, dzięki czemu żadna treść nie wyświetla się w obszarze wycięcia.

Renderuj treść w obszarach z krótszymi wycięciami

W przypadku niektórych treści, np. filmów, zdjęć, map i gier, renderowanie w obszarze wycięcia może być świetnym sposobem na zapewnienie użytkownikom bardziej atrakcyjnych wrażeń. W przypadku LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES zawartość obejmuje obszar wycięcia przy 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 zasłaniają obszaru wycięcia.

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

Obraz pokazujący treści renderowane w obszarze wycięcia w trybie portretowym
Rysunek 2. W trybie pionowym treści są renderowane w obszarze wycięcia.

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

Obraz pokazujący treść renderowaną w obszarze wycięcia w trybie poziomym
Rysunek 3. W trybie poziomym treści są renderowane w obszarze wycięcia.

W tym trybie okno wychodzi poza wycięcie przy krótszej krawędzi wyświetlacza, zarówno w orientacji pionowej, jak i poziomej, niezależnie od tego, czy okno zakrywa paski systemowe.

Wycięcie w rogu uznajemy za wycięcie na krótszej krawędzi:

Obraz przedstawiający urządzenie z wycięciem w rogu
Rysunek 4. Urządzenie z wycięciem w rogu.

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

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

Oto przykład użycia funkcji LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w orientacji pionowej:

Obraz przedstawiający LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w orientacji pionowej
Rysunek 5. Przykład LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w trybie portretowym.

Oto przykład elementu LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w trybie poziomym:

Obraz przedstawiający LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w trybie poziomym
Rysunek 6. Przykład elementu LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER w orientacji poziomej.

Sprawdzone metody obsługi wycięcia w ekranie

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

  • Pamiętaj o rozmieszczeniu kluczowych elementów interfejsu. Nie pozwól, by wycięcie w tekście zasłaniało tekst, elementy sterujące lub inne informacje.
  • W obszarze wycięcia nie umieszczaj ani nie rozszerzaj żadnych elementów interaktywnych, które wymagają dokładnego rozpoznania. Czułość w zakresie dotyku może być niższa w obszarze wycięcia.
  • W miarę możliwości 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 spowodować nakładanie się lub ucinanie treści.

    Grafika przedstawiająca treść przyciętą u góry z powodu nieprawidłowego ustawienia wstawek
    Rysunek 7. Użyj narzędzia WindowInsetsCompat, aby uniknąć nakładania się lub przycinania treści.
  • Użyj View.getLocationInWindow(), aby określić, ile miejsca w oknie używa aplikacja. Nie zakładaj, że aplikacja używa całego okna i nie używaj funkcji View.getLocationOnScreen().

  • Jeśli aplikacja musi przechodzić w tryb pojemny lub z niego wyjść, użyj trybu wycinania shortEdges lub never. Domyślne zachowanie w przypadku wycięcia może powodować, że treści w aplikacji będą renderowane w obszarze wycięcia, gdy widoczne są paski systemowe, ale nie w trybie pojemnym. Powoduje to przemieszczanie się treści w górę i w dół podczas przenoszenia, jak widać w poniższym przykładzie.

    Obraz przedstawiający treści poruszające się w górę i w dół podczas przejść.
    Rysunek 8. Przykład treści poruszających się w górę i w dół podczas przejść.
  • W trybie pojemnym zachowaj ostrożność, używając współrzędnych okna, a nie ekranu, ponieważ aplikacja nie zajmuje całego ekranu. Ze względu na skrzynkę współrzędnych współrzędne z początku ekranu różnią się od współrzędnych z początku okna. Korzystając z funkcji getLocationOnScreen(), możesz przekształcić współrzędne ekranu na współrzędne widoku. Poniższy obraz pokazuje, jak różnią się współrzędne, gdy zawartość ma czarne pasy:

    Obraz pokazujący współrzędne okna i ekranu, gdy zawartość ma czarne pasy.
    Rysunek 9. Współrzędne okna i ekranu, gdy treść ma czarne pasy.
  • Podczas obsługi obiektów MotionEvent używaj MotionEvent.getX() i MotionEvent.getY(), aby uniknąć podobnych problemów ze współrzędnymi. Nie używaj właściwości MotionEvent.getRawX() ani MotionEvent.getRawY().

Testowanie renderowania treści

Przetestuj wszystkie ekrany i sposoby działania aplikacji. Jeśli to możliwe, przetestuj ją na urządzeniach z różnymi wycięciami. Jeśli nie masz urządzenia z wycięciem, możesz przeprowadzić symulację typowych konfiguracji wycięcia na dowolnym urządzeniu lub w emulatorze z Androidem 9 lub nowszym. Aby to zrobić, wykonaj 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 dla programistów dotyczące testowania renderowania treści.

Dodatkowe materiały