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](https://developer.android.google.cn/static/develop/ui/views/layout/display-cutout/images/cutout-intro.png?authuser=8&hl=pl)
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:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
: treść renderuje się w obszarze wycięcia, gdy wycięcie w ekranie znajduje się na pasku systemowym. W przeciwnym razie okno nie nakłada się na wycięcie w ekranie, np. przy wyświetlaniu w trybie poziomym treści mogą mieć czarne pasy. Jeśli aplikacja jest kierowana na pakiet SDK 35, w przypadku okien niepływających zostanie to zinterpretowane jakoALWAYS
.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
: treść zawsze może się rozszerzać na obszary wycięcia. Jeśli Twoja aplikacja jest kierowana na pakiet SDK 35 i działa na urządzeniu z Androidem 15, jest to jedyny dozwolony tryb w oknach niepływających, który zapewnia obraz od krawędzi do krawędzi.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
: treść renderuje się w obszarze wycięcia zarówno w orientacji pionowej, jak i poziomej. Nie używaj jej w przypadku okna pływających. Jeśli Twoja aplikacja jest kierowana na pakiet SDK 35, w przypadku okien niepływających zostanie to zinterpretowane jakoALWAYS
.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
: treść nigdy nie jest renderowana w obszarze wycięcia. Jeśli Twoja aplikacja jest kierowana na pakiet SDK 35, w przypadku okien niepływających jest to interpretowane jakoALWAYS
.
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
Jeśli Twoja aplikacja jest kierowana na pakiet SDK 35 i działa na urządzeniu z Androidem 15, domyślnym działaniem jest LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
, a LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
jest interpretowany jako LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
w przypadku 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, w przypadku okien niepływających funkcja LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
jest interpretowana jako LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
.
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](https://developer.android.google.cn/static/develop/ui/views/layout/display-cutout/images/cutout-short-edges-1.png?authuser=8&hl=pl)
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](https://developer.android.google.cn/static/develop/ui/views/layout/display-cutout/images/cutout-short-edges-2.png?authuser=8&hl=pl)
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](https://developer.android.google.cn/static/develop/ui/views/layout/display-cutout/images/cutout-corner.png?authuser=8&hl=pl)
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, w przypadku okien niepływających funkcja LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
jest interpretowana jako LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
.
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](https://developer.android.google.cn/static/develop/ui/views/layout/display-cutout/images/cutout-never.png?authuser=8&hl=pl)
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](https://developer.android.google.cn/static/develop/ui/views/layout/display-cutout/images/cutout-never-landscape.png?authuser=8&hl=pl)
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.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żywajView.getLocationOnScreen()
.Jeśli aplikacja musi przejść do trybu pojemnego lub z niego wyjść, użyj trybów
always
,shortEdges
lubnever
. Domyślne działanie wycięcia może spowodować renderowanie treści w aplikacji 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 przejść, jak widać na przykładzie poniżej.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:Rysunek 9. Współrzędne okna i ekranu, gdy treść jest otoczona czarnymi pasami. Podczas obsługi funkcji
MotionEvent
użyjMotionEvent.getX()
iMotionEvent.getY()
, aby uniknąć podobnych problemów ze współrzędnymi. Nie używajMotionEvent.getRawX()
aniMotionEvent.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ć:
- Włącz Opcje programisty.
- Na ekranie Opcje programisty przewiń w dół do sekcji Rysowanie i wybierz Symuluj ekran z wycięciem.
Wybierz typ wycięcia.
Rysunek 10. Opcje programisty umożliwiające przetestowanie renderowania treści.
Dodatkowe materiały
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT