Wyświetlaj zawartość w aplikacji od krawędzi do krawędzi

Wypróbuj sposób tworzenia wiadomości
Jetpack Compose to zalecany zestaw narzędzi interfejsu na Androida. Dowiedz się, jak korzystać z wersji od brzegu do krawędzi w Compose

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 pasek aplikacji u góry. Górny pasek aplikacji powinien rozciągać się do górnej krawędzi ekranu i wyświetlać za paskiem stanu. Opcjonalnie, gdy treści są przewijane, górny pasek aplikacji może się zwijać do wysokości paska stanu.

Wiele aplikacji ma też pasek aplikacji lub pasek nawigacyjny u dołu ekranu. Paski powinny się rozcią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.

Rysunek 1. Paski systemowe w układzie od krawędzi do krawędzi.

Podczas implementowania w aplikacji układu od krawędzi do krawędzi pamiętaj o tych kwestiach:

  1. Włącz wyświetlanie bez ramki
  2. Rozwiązuj problemy z wizualnymi nakładającymi się treściami.
  3. Rozważ wyświetlanie ram za pasami systemowymi.
przykład obrazu za paskiem stanu.
Rysunek 2. Przykład obrazów za paskiem stanu

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 od krawędzi do krawędzi w poprzednich wersjach Androida:

  1. Aby dodać zależność do biblioteki androidx.activity w pliku build.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'
    }
  2. Zaimportuj funkcję rozszerzenia enableEdgeToEdge do swojej aplikacji:

Ręcznie włącz połączenia od brzegu do brzegu, wywołując metodę enableEdgeToEdge w onCreate z 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 (patrz rysunek 3).

Możesz rozwiązać problem z nakładaniem się, reagując na wcięcia określające, które części ekranu przecinają się z interfejsem systemowym, 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 od krawędzi do krawędzi:

  • Wstawki systemowe w postaci słupków: najlepiej sprawdzają się w przypadku widoków, które można kliknąć i które nie mogą być zasłonięte słupkami systemowymi.

  • Wstawki na wycięcia w ekranie: dla obszarów, w których może występować 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 jest wyświetlany 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 (FAB) na rysunku 3 jest częściowo zasłonięty przez pasek nawigacyjny:

przykład wdrożenia od krawędzi do krawędzi, ale pasek nawigacyjny zasłania przycisk szybkiego dostępu;
Rysunek 3. Pasek nawigacyjny zachodzący na przycisk FAB w układzie od krawędzi do krawędzi

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)WindowInsetsCompat.Type.systemBars().

Poniższy przykładowy kod pokazuje, jak wdrożyć systemowe wstawki słupkowe:

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 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 want the window insets to keep passing
  // down to descendant views.
    return WindowInsetsCompat.CONSUMED;
});

Jeśli zastosujesz to rozwiązanie w przypadku przykładu przedstawionego na rysunku 3, nie będzie żadnego wizualnego nakładania się w trybie przycisku, jak pokazano na rysunku 4:

przezroczysty pasek nawigacyjny, który nie zasłania przycisku FAB;
Rysunek 4. Rozwiązywanie problemów z nakładaniem się elementów wizualnych w trybie przycisku.

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

bez ramki z nawigacją przy użyciu gestów
Rysunek 5. Rozwiązywanie problemu z nakładaniem się elementów wizualnych w trybie nawigacji przy użyciu gestów.

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 wdrożyć wypełnienie, aby uniknąć wyświetlania treści na wycięciach ekranu. Domyślnie aplikacje będą rysować na 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 określa się logicznie lub na podstawie pasków systemu i typów wycięć wyświetlacza.

Ustaw wartość clipToPadding na RecyclerView, aby wypełnienie przewijało się razem z elementami listy. Dzięki temu elementy mogą pojawiać się za paskami systemowymi, gdy użytkownik przewija stronę, jak w przykładzie poniżej.

<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" />

Systemowe wstawki gesty

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:

Przykład systemowego wstawienia gestów
Rysunek 6. Wstawki gestów systemowych.

Podobnie jak w przypadku wstawionych elementów paska systemowego możesz uniknąć nakładania się wstawionych elementów 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 zaimplementowane za pomocą ViewPager2.

W Androidzie 10 i nowszych wstawki systemowe zawierają dolną wkładkę dla gestu Home oraz wcięcie lewą i prawą dla gestów cofania.

przykład pomiarów wstawionych gestami systemowymi
Rysunek 7. pomiary wstawionych gestów systemowych.

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

Oparte na widokach komponenty Android Material Komponenty (com.google.android.material){:.external} automatycznie obsługują wstawki, w tym BottomAppBar, BottomNavigationView, NavigationRailView i NavigationView

Jednak AppBarLayout nie będzie automatycznie obsługiwać wkładek. Dodaj android:fitsSystemWindows="true" , aby obsłużyć wstawione elementy.

Dowiedz się, jak obsługiwać wstawki za pomocą komponentów Material Materialowych w narzędziu Compose.

Tryb imersji

Niektóre treści najlepiej oglądać na pełnym ekranie, co zapewnia użytkownikowi bardziej wciągające wrażenia. Możesz ukryć paski systemowe i użyć trybu pełnoekranowego, korzystając z bibliotek WindowInsetsControllerWindowInsetsControllerCompat:

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.

Ochrona paska systemu

Gdy Twoja aplikacja jest kierowana na pakiet SDK 35 lub nowszą wersję, egzekwowana jest weryfikacja od początku do końca. Pasek stanu systemu i paski nawigacji przy użyciu gestów są przezroczyste, ale pasek nawigacji z 3 przyciskami jest półprzezroczysty.

Aby usunąć domyślną przezroczystą ochronę tła nawigacji z 3 przyciskami, ustaw wartość Window.setNavigationBarContrastEnforced na false.

Dodatkowe materiały

Aby dowiedzieć się więcej o WindowInsets, nawigacji za pomocą gestów i działaniu wstawek, zapoznaj się z tymi materiałami: