Gdy kierujesz aplikację na pakiet SDK 35 lub nowszy na urządzeniu z Androidem 15 lub nowszym, będzie ona wyświetlana bez ramki. Okno rozciąga się na całą szerokość i wysokość wyświetlacza, wyświetlając się za paskami systemu. Paski systemowe to pasek stanu, pasek podpisów i pasek nawigacji.
Wiele aplikacji ma górny pasek aplikacji. Górny pasek aplikacji powinien sięgać do górnej krawędzi ekranu i wyświetlać się za paskiem stanu. Opcjonalnie pasek aplikacji u góry może się zmniejszać do wysokości paska stanu podczas przewijania treści.
Wiele aplikacji ma też pasek aplikacji lub pasek nawigacji na dole ekranu. Te paski powinny sięgać do dolnej krawędzi ekranu i wyświetlać się za paskiem nawigacyjnym. W przeciwnym razie aplikacje powinny wyświetlać przewijane treści za paskiem nawigacyjnym.
Podczas implementowania w aplikacji układu od krawędzi do krawędzi pamiętaj o tych kwestiach:
- Włącz wyświetlanie bez ramki
- Zadbaj o to, aby nie było nakładania się elementów.
- Rozważ wyświetlanie ekranów ładowania za paskami systemowymi.

Włącz wyświetlanie bez ramki
Jeśli Twoja aplikacja jest kierowana na pakiet SDK 35 lub nowszy, wyświetlanie bez ramki jest automatycznie włączone na urządzeniach z Androidem 15 lub nowszym.
Aby włączyć tryb pełnoekranowy w poprzednich wersjach Androida:
Aby dodać zależność do biblioteki
androidx.activity
w plikubuild.gradle
aplikacji lub modułu:Kotlin
dependencies { val activity_version =
activity_version
// Java language implementation implementation("androidx.activity:activity:$activity_version") // Kotlin implementation("androidx.activity:activity-ktx:$activity_version") }Groovy
dependencies { def activity_version =
activity_version
// Java language implementation implementation 'androidx.activity:activity:$activity_version' // Kotlin implementation 'androidx.activity:activity-ktx:$activity_version' }Zaimportuj funkcję rozszerzenia
enableEdgeToEdge
do swojej aplikacji:
Ręcznie włącz wyświetlanie bez ramki, wywołując enableEdgeToEdge
w onCreate
Activity
. Powinien być wywoływany przed setContentView
.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) ... }
Java
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { EdgeToEdge.enable(this); super.onCreate(savedInstanceState); ... }
Domyślnie enableEdgeToEdge()
sprawia, że paski systemowe stają się przezroczyste, z wyjątkiem trybu nawigacji z 3 przyciskami, w którym pasek stanu staje się półprzezroczysty. Kolory ikon systemowych i przesłony są dostosowywane na podstawie jasnego lub ciemnego motywu systemu.
Funkcja enableEdgeToEdge()
automatycznie deklaruje, że aplikacja powinna być rozmieszczona od krawędzi do krawędzi, i dostosowuje kolory pasków systemu.
Aby włączyć wyświetlanie bez ramki w aplikacji bez używania funkcji enableEdgeToEdge()
, przeczytaj artykuł Ręczne konfigurowanie wyświetlania bez ramki.
Obsługa nakładania się za pomocą wstawek
Niektóre widoki aplikacji mogą być wyświetlane za paskami systemu, jak pokazano na rysunku 3.
Możesz rozwiązać problem z nakładaniem się elementów, reagując na wstawki, które określają, które części ekranu pokrywają się z interfejsem systemu, takim jak pasek nawigacyjny lub pasek stanu. Przecięcie może oznaczać wyświetlanie nad treścią, ale może też informować aplikację o gestach systemowych.
Typy wstawek, które mają zastosowanie do wyświetlania aplikacji bez ramki:
Pasek systemowy w ramce: najlepiej nadaje się do widoków, które można dotknąć i które nie mogą być zasłonięte przez pasek systemowy.
Wstawki na wycięcia w ekranie: obszary, w których może znajdować się wycięcie w ekranie ze względu na kształt urządzenia.
Wstawki gestów systemowych: obszary nawigacji za pomocą gestów używane przez system, które mają wyższy priorytet niż aplikacja.
Wstawki pasków systemowych
Wstawki w pasku systemowym to najczęściej używany typ wstawek. Odpowiadają one obszarowi, w którym interfejs użytkownika systemu wyświetla się na osi Z nad aplikacją. Najlepiej używać ich do przenoszenia lub wypełniania widoków w aplikacji, które można dotykać i które nie mogą być zasłonięte przez paski systemu.
Na przykład pływający przycisk akcji na rysunku 3 jest częściowo zasłonięty przez pasek nawigacyjny:

Aby uniknąć takiego nakładania się elementów w trybie gestów lub przycisków, możesz zwiększyć marginesy widoku za pomocą getInsets(int)
w WindowInsetsCompat.Type.systemBars()
.
Poniższy przykładowy kod pokazuje, jak zastosować wstawki paska systemowego:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) // Apply the insets as a margin to the view. This solution sets // only the bottom, left, and right dimensions, but you can apply whichever // insets are appropriate to your layout. You can also update the view padding // if that's more appropriate. v.updateLayoutParams<MarginLayoutParams> { leftMargin = insets.left bottomMargin = insets.bottom rightMargin = insets.right } // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); // Apply the insets as a margin to the view. This solution sets only the // bottom, left, and right dimensions, but you can apply whichever insets are // appropriate to your layout. You can also update the view padding if that's // more appropriate. MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams(); mlp.leftMargin = insets.left; mlp.bottomMargin = insets.bottom; mlp.rightMargin = insets.right; v.setLayoutParams(mlp); // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. return WindowInsetsCompat.CONSUMED; });
Jeśli zastosujesz to rozwiązanie w przypadku przykładu na rysunku 3, nie będzie już wizualnego nakładania się w trybie przycisku, jak widać na rysunku 4:

To samo dotyczy trybu nawigacji przy użyciu gestów, jak pokazano na rysunku 5:

Wyświetlanie wstawek w wycięciu
Niektóre urządzenia mają wycięcia na wyświetlaczu. Zwykle wycięcie znajduje się u góry ekranu i wchodzi na pasek stanu. Gdy ekran urządzenia jest w orientacji poziomej, wycięcie może znajdować się na krawędzi pionowej. W zależności od treści wyświetlanych przez aplikację na ekranie należy zastosować wypełnienie, aby uniknąć wyświetlania treści w wycięciach ekranu. Domyślnie aplikacje będą wyświetlać treści w wycięciach ekranu.
Na przykład wiele ekranów aplikacji zawiera listę elementów. Nie zasłaniaj elementów listy wycięciem w ekranie ani paskami systemu.
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets -> val bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() ) v.updatePadding( left = bars.left, top = bars.top, right = bars.right, bottom = bars.bottom, ) WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> { Insets bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() ); v.setPadding(bars.left, bars.top, bars.right, bars.bottom); return WindowInsetsCompat.CONSUMED; });
Wartość WindowInsetsCompat
można określić, stosując operator logiczny lub do systemowych pasków i typów wycięć wyświetlacza.
Ustaw wartość clipToPadding
na RecyclerView
, aby wypełnienie przewijało się razem z elementami listy. Pozwala to na ukrycie elementów za paskami systemowymi, gdy użytkownik przewija ekran, jak pokazano w tym przykładzie.
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
Wstawki gestów systemowych
Wstawki gestów systemowych to obszary okna, w których gesty systemowe mają wyższy priorytet niż aplikacja. Na rysunku 6 obszary te są oznaczone na pomarańczowo:

Podobnie jak w przypadku wstawek w pasku systemowym, możesz uniknąć nakładania się wstawek gestów systemowych, używając
getInsets(int)
WindowInsetsCompat.Type.systemGestures()
.
Za pomocą tych wstawek możesz przesuwać widoki, które można przesuwać, od krawędzi. Typowe przypadki użycia to karty dolne, przesuwanie w grach i karuzele implementowane za pomocą ViewPager2
.
W Androidzie 10 lub nowszym odcięcia gestów systemowych obejmują odcięcie dolne dla gestu powrotu do ekranu głównego oraz odcięcia po lewej i prawej stronie dla gestów wstecz:

Poniższy przykład kodu pokazuje, jak zastosować wstawki gestów systemowych:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.updatePadding(insets.left, insets.top, insets.right, insets.bottom) // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()); // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.setPadding(insets.left, insets.top, insets.right, insets.bottom); // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. return WindowInsetsCompat.CONSUMED; });
Material Components
Wiele widoków opartych na komponentach Material Design dla Androida (com.google.android.material) automatycznie obsługuje wstawki, w tym BottomAppBar
, BottomNavigationView
, NavigationRailView
i NavigationView
.
Jednak AppBarLayout
nie obsługuje automatycznie wstawionych elementów. Dodaj
android:fitsSystemWindows="true"
, aby obsłużyć wstawione elementy.
Dowiedz się, jak obsługiwać w komponentach Material w Compose elementy wsunięte.
Zgodność wsteczna w przypadku przesyłania wstawek
Aby zatrzymać przesyłanie wstawek do widoków podrzędnych i uniknąć nadmiernego wypełniania, możesz używać wstawek za pomocą stałej wartości WindowInsetsCompat.CONSUMED
. Jednak na urządzeniach z Androidem 10 (poziom interfejsu API 29 i starsze) wstawki nie są wysyłane do elementów podrzędnych po wywołaniu metody WindowInsetsCompat.CONSUMED
, co może powodować niezamierzone nakładanie się elementów.

Aby upewnić się, że w przypadku wszystkich obsługiwanych wersji Androida wstawki są wysyłane do elementów podrzędnych, przed użyciem wstawek użyj funkcji ViewGroupCompat#installCompatInsetsDispatch
, która jest dostępna w AndroidX Core i Core-ktx w wersji 1.16.0-alpha01 lub nowszej.
Kotlin
// Use the i.d. assigned to your layout's root view, e.g. R.id.main val rootView = findViewById(R.id.main) // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView)
Java
// Use the i.d. assigned to your layout's root view, e.g. R.id.main LinearLayout rootView = findViewById(R.id.main); // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView);

Tryb imersji
Niektóre treści najlepiej oglądać na pełnym ekranie, co zapewnia użytkownikom bardziej wciągające wrażenia. Możesz ukryć paski systemowe i użyć trybu pełnoekranowego, korzystając z bibliotek WindowInsetsController
i WindowInsetsControllerCompat
:
Kotlin
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) // Hide the system bars. windowInsetsController.hide(Type.systemBars()) // Show the system bars. windowInsetsController.show(Type.systemBars())
Java
Window window = getWindow(); WindowInsetsControllerCompat windowInsetsController = WindowCompat.getInsetsController(window, window.getDecorView()); if (windowInsetsController == null) { return; } // Hide the system bars. windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); // Show the system bars. windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
Więcej informacji o wdrażaniu tej funkcji znajdziesz w artykule Ukrywanie pasków systemowych w trybie pełnoekranowym.
Ikony na pasku systemu
Wywołanie enableEdgeToEdge
zapewnia aktualizację kolorów ikon na pasku systemu po zmianie motywu urządzenia.
Podczas przekształcania aplikacji na tryb pełnoekranowy może być konieczne ręczne zaktualizowanie kolorów ikony na pasku systemowym, aby kontrastowały z tłem aplikacji. Aby na przykład utworzyć jasne ikony paska stanu:
Kotlin
WindowCompat.getInsetsController(window, window.decorView) .isAppearanceLightStatusBars = false
Java
WindowCompat.getInsetsController(window, window.getDecorView()) .setAppearanceLightStatusBars(false);
Ochrona paska systemu
Gdy Twoja aplikacja będzie kierowana na pakiet SDK 35 lub nowszy, wymagana będzie obsługa obrazu od krawędzi do krawędzi.
Pasek stanu systemu i paski nawigacji przy użyciu gestów są przezroczyste, ale pasek nawigacji z 3 przyciskami jest półprzezroczysty. Aby zapewnić zgodność wsteczną, zadzwoń pod numer enableEdgeToEdge
.
Domyślne ustawienia systemu mogą jednak nie działać w przypadku niektórych przypadków użycia. Aby określić, czy użyć przezroczystych czy półprzezroczystych pasków systemu, zapoznaj się z wskazówkami dotyczącymi projektowania pasków systemu Androida i projektowania sięgającego krawędzi ekranu.
Tworzenie przezroczystych pasków systemu
Aby utworzyć przezroczysty pasek stanu, kieruj na Androida 15 (pakiet SDK 35) lub nowszego albo wywołuj funkcję enableEdgeToEdge()
z domyślnymi argumentami w przypadku starszych wersji.
Utwórz przezroczysty pasek nawigacyjny gestów, kierując się na Androida w wersji 15 lub nowszej lub wywołując enableEdgeToEdge()
z domyślnymi argumentami w przypadku starszych wersji. W przypadku paska nawigacyjnego z 3 przyciskami ustaw wartość Window.setNavigationBarContrastEnforced
na false
. W przeciwnym razie zostanie zastosowana półprzezroczysta zasłona.
Tworzenie przezroczystych pasków systemu
Aby utworzyć przezroczysty pasek stanu:
- Zaktualizuj zależność
androidx-core
do wersji 1.16.0-beta01 lub nowszej. - Zawiń układ XML w element
androidx.core.view.insets.ProtectionLayout
i przypisz mu identyfikator. - Za pomocą kodu uzyskaj dostęp do
ProtectionLayout
, aby skonfigurować zabezpieczenia, określając stronę iGradientProtection
z 80% przezroczystością dla paska stanu.
<androidx.core.view.insets.ProtectionLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/list_protection" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView android:id="@+id/item_list" android:clipToPadding="false" android:layout_width="match_parent" android:layout_height="match_parent"> <!--items--> </ScrollView> </androidx.core.view.insets.ProtectionLayout>
val red = 52 val green = 168 val blue = 83 findViewById<ProtectionLayout>(R.id.list_protection) .setProtections( listOf( GradientProtection( WindowInsetsCompat.Side.TOP, // Ideally, this is the pane's background color // alpha = 204 for an 80% gradient Color.argb(204, red, green, blue) ) ) )
Upewnij się, że ColorInt
przekazane do GradientProtection
pasuje do tła treści. Na przykład układ z listą i szczegółami wyświetlany na urządzeniu składanym może mieć różne GradientProtections
w różnych kolorach w panelu listy i panelu szczegółów.
Nie twórz przezroczystego paska nawigacyjnego sterowanego gestami. Aby utworzyć przezroczystą belkę nawigacyjną z 3 przyciskami, wykonaj jedną z tych czynności:
- Jeśli masz już układ ujęty w funkcji
ProtectionView
, możesz przekazać dodatkowej funkcjiProtectionView
lubGradientProtection
metodęsetProtections
.ColorProtection
Zanim to zrobisz, sprawdź, czywindow.isNavigationBarContrastEnforced = false
. - W przeciwnym razie ustaw
window.isNavigationBarContrastEnforced = true
. Jeśli Twoja aplikacja wywołuje funkcjęenableEdgeToEdge, window.isNavigationBarContrastEnforced = true
, jest to domyślne.
Inne wskazówki
Sprawdź, czy ostatni element listy nie jest zasłonięty przez paski systemu w Twoim
RecyclerView
lub NestedScrollView
, obsługując wstawki i ustawiając
clipToPadding
na false
.
Ten film pokazuje RecyclerView
z wyświetlaczem od krawędzi do krawędzi wyłączonym (po lewej) i włączonym (po prawej):
Przykładowy kod znajdziesz w sekcji Tworzenie dynamicznych list za pomocą RecyclerView.
Dodatkowe materiały
Więcej informacji o przechodzeniu na wyświetlanie od krawędzi do krawędzi znajdziesz w tych materiałach.
Blogi
- Wskazówki dotyczące obsługi wcięć w Androidzie 15 z wymuszonym wyświetlaniem na całą szerokość ekranu
- WindowInsets – listenerów układów
Design
Inna dokumentacja
Filmy