Menampilkan konten layar penuh dalam tampilan

Mencoba cara Compose
Jetpack Compose adalah toolkit UI yang direkomendasikan untuk Android. Pelajari cara menggunakan tampilan layar penuh di Compose.

Setelah Anda menargetkan SDK 35 atau yang lebih tinggi di perangkat yang menjalankan Android 15 atau yang lebih tinggi, aplikasi Anda akan ditampilkan dalam layar penuh. Jendela mencakup seluruh lebar dan tinggi layar dengan menggambar di belakang kolom sistem. Kolom sistem mencakup status bar, kolom teks, dan menu navigasi.

Banyak aplikasi memiliki panel aplikasi atas. Panel aplikasi atas harus membentang ke tepi atas layar dan ditampilkan di belakang status bar. Secara opsional, panel aplikasi atas dapat menyusut hingga setinggi status bar saat konten di-scroll.

Banyak aplikasi juga memiliki panel aplikasi bawah atau menu navigasi bawah. Panel ini juga harus membentang ke tepi bawah layar dan ditampilkan di belakang menu navigasi. Jika tidak, aplikasi harus menampilkan konten scroll di belakang menu navigasi.

Gambar 1. Kolom sistem dalam tata letak layar penuh.

Saat menerapkan tata letak layar penuh di aplikasi Anda, perhatikan hal-hal berikut:

  1. Mengaktifkan tampilan layar penuh
  2. Terapkan tata letak adaptif untuk mengoptimalkan pengalaman pengguna di berbagai faktor bentuk
  3. Menangani tumpang-tindih visual
  4. Pertimbangkan untuk menampilkan scrim di belakang kolom sistem
contoh gambar di belakang status bar
Gambar 2. Contoh gambar di balik status bar.

Aktifkan layar penuh

Jika aplikasi Anda menargetkan SDK 35 atau yang lebih baru, tampilan layar penuh akan otomatis diaktifkan untuk perangkat Android 15 atau yang lebih baru.

Untuk mengaktifkan tampilan layar penuh di versi Android sebelumnya, panggil enableEdgeToEdge secara manual di onCreate dari Activity Anda.

Kotlin

 override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         WindowCompat.enableEdgeToEdge(window)
        ...
      }

Java

 @Override
      protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        WindowCompat.enableEdgeToEdge(getWindow());
        ...
      }

Secara default, enableEdgeToEdge() membuat kolom sistem menjadi transparan, kecuali pada mode navigasi 3 tombol, yang membuat menu navigasi mendapatkan scrim transparan. Warna ikon sistem dan scrim disesuaikan berdasarkan tema terang atau gelap sistem.

Untuk mengaktifkan tampilan layar penuh di aplikasi Anda tanpa menggunakan fungsi enableEdgeToEdge(), lihat Menyiapkan tampilan layar penuh secara manual.

Menangani tumpang-tindih menggunakan inset

Beberapa tampilan aplikasi Anda mungkin digambar di belakang kolom sistem, seperti yang ditunjukkan pada gambar 3.

Anda dapat mengatasi tumpang-tindih dengan bereaksi terhadap inset, yang menentukan bagian layar mana yang berpotongan dengan UI sistem seperti menu navigasi atau status bar. Berpotongan dapat berarti menampilkan di atas konten, tetapi juga dapat memberi tahu aplikasi Anda tentang gestur sistem.

Jenis inset yang berlaku untuk menampilkan aplikasi Anda dalam mode layar penuh adalah:

  • Inset kolom sistem: paling cocok untuk tampilan yang dapat diketuk dan tidak boleh tertutup secara visual oleh kolom sistem.

  • Inset potongan layar: untuk area yang mungkin memiliki potongan layar karena bentuk perangkat.

  • Inset gestur sistem: untuk area navigasi gestur yang digunakan oleh sistem yang lebih diprioritaskan daripada aplikasi Anda.

Inset kolom sistem

Inset kolom sistem adalah jenis inset yang paling umum digunakan. Inset ini mewakili area tempat UI sistem ditampilkan di sumbu Z di atas aplikasi Anda. Inset ini paling baik digunakan untuk memindahkan atau memberi padding pada tampilan di aplikasi Anda yang dapat diketuk dan tidak boleh tertutup secara visual oleh kolom sistem.

Misalnya, tombol tindakan mengambang (FAB) pada gambar 3 sebagian terhalang oleh menu navigasi:

contoh penerapan layar penuh, tetapi menu navigasi menutupi FAB
Gambar 3. Menu navigasi yang tumpang-tindih dengan FAB dalam tata letak layar penuh.

Untuk menghindari tumpang-tindih visual semacam ini dalam mode gestur atau mode tombol, Anda dapat meningkatkan margin tampilan menggunakan getInsets(int) dengan WindowInsetsCompat.Type.systemBars().

Contoh kode berikut menunjukkan cara menerapkan inset kolom sistem:

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;
});

Jika Anda menerapkan solusi ini ke contoh yang ditampilkan pada gambar 3, tidak akan ada tumpang-tindih visual dalam mode tombol, seperti yang ditunjukkan pada gambar 4:

bilah navigasi transparan yang tidak menutupi FAB
Gambar 4. Menyelesaikan tumpang-tindih visual dalam mode tombol.

Hal yang sama berlaku untuk mode navigasi gestur, seperti yang ditunjukkan pada gambar 5:

tata letak layar penuh dengan navigasi gestur
Gambar 5. Menyelesaikan tumpang-tindih visual dalam mode navigasi gestur.

Inset potongan layar

Beberapa perangkat memiliki potongan layar. Biasanya, potongan berada di bagian atas layar dan disertakan dalam status bar. Saat layar perangkat dalam mode lanskap, potongan mungkin berada di tepi vertikal. Bergantung pada konten yang ditampilkan aplikasi di layar, Anda harus menerapkan padding untuk menghindari potongan layar, karena secara default, aplikasi akan menggambar di potongan layar.

Misalnya, banyak layar aplikasi menampilkan daftar item. Jangan mengaburkan item daftar dengan potongan layar atau kolom sistem.

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;
});

Tentukan nilai WindowInsetsCompat dengan mengambil or logis dari kolom sistem dan jenis potongan layar.

Tetapkan clipToPadding ke RecyclerView agar padding di-scroll bersama item daftar. Hal ini memungkinkan item berada di belakang kolom sistem saat pengguna men-scroll, seperti yang ditunjukkan dalam contoh berikut.

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

Inset gestur sistem

Inset gestur sistem mewakili area jendela tempat gestur sistem lebih diprioritaskan daripada aplikasi Anda. Area ini ditampilkan dalam warna oranye pada gambar 6:

Contoh inset gestur sistem
Gambar 6. Inset gestur sistem.

Seperti inset kolom sistem, Anda dapat menghindari tumpang-tindih inset gestur sistem menggunakan getInsets(int) dengan WindowInsetsCompat.Type.systemGestures().

Gunakan inset ini untuk memindahkan atau memberi padding pada tampilan yang dapat digeser agar menjauh dari tepi. Kasus penggunaan umum mencakup panel bawah, geser dalam game, dan carousel yang diimplementasikan menggunakan ViewPager2.

Di Android 10 atau yang lebih baru, inset gestur sistem berisi inset bawah untuk gestur layar utama, serta inset kiri dan kanan untuk gestur kembali:

contoh pengukuran inset gestur sistem
Gambar 7. Pengukuran inset gestur sistem.

Contoh kode berikut menunjukkan cara menerapkan inset gestur sistem:

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;
});

Komponen Material

Banyak Komponen Material Android berbasis tampilan (com.google.android.material) otomatis menangani inset, termasuk BottomAppBar, BottomNavigationView, NavigationRailView, dan NavigationView

Namun, AppBarLayout tidak otomatis menangani inset. Tambahkan android:fitsSystemWindows="true" untuk menangani inset atas.

Baca cara menangani inset dengan Komponen Material di Compose.

Pengiriman inset yang kompatibel dengan versi lama

Untuk menghentikan pengiriman inset ke tampilan turunan dan menghindari padding berlebih, Anda dapat menggunakan inset menggunakan konstanta WindowInsetsCompat.CONSUMED. Namun, di perangkat yang menjalankan Android 10 (level API 29 dan yang lebih rendah), inset tidak dikirim ke elemen seinduk setelah memanggil WindowInsetsCompat.CONSUMED, yang dapat menyebabkan tumpang-tindih visual yang tidak diinginkan.

Contoh pengiriman inset yang rusak
Gambar 8. Contoh pengiriman inset yang rusak. Inset tidak dikirim ke tampilan yang seinduk setelah ViewGroup 1 memakai inset di Android 10 (level API 29) dan yang lebih lama, sehingga menyebabkan TextView 2 tumpang-tindih dengan menu navigasi sistem. Namun, inset dikirim ke tampilan yang setara di Android 11 (level API 30) dan yang lebih tinggi, seperti yang diharapkan.

Untuk mengonfirmasi bahwa inset dikirim ke elemen seinduk untuk semua versi Android yang didukung, gunakan ViewGroupCompat#installCompatInsetsDispatch sebelum menggunakan inset, yang tersedia di AndroidX Core dan Core-ktx 1.16.0-alpha01 dan yang lebih tinggi.

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);
Contoh pengiriman inset tetap
Gambar 9. Memperbaiki pengiriman inset setelah memanggil ViewGroupCompat#installCompatInsetsDispatch.

Mode imersif

Beberapa konten paling baik dinikmati dalam layar penuh, sehingga memberikan pengalaman yang lebih imersif kepada pengguna. Anda dapat menyembunyikan kolom sistem untuk mode imersif menggunakan library WindowInsetsController dan 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());

Lihat Menyembunyikan kolom sistem untuk mode imersif untuk mengetahui informasi selengkapnya tentang cara menerapkan fitur ini.

Ikon kolom sistem

Memanggil enableEdgeToEdge akan memastikan warna ikon kolom sistem diperbarui saat tema perangkat berubah.

Saat menggunakan tampilan layar penuh, Anda mungkin perlu memperbarui warna ikon kolom sistem secara manual agar kontras dengan latar belakang aplikasi. Misalnya, untuk membuat ikon status bar terang:

Kotlin

WindowCompat.getInsetsController(window, window.decorView)
    .isAppearanceLightStatusBars = false

Java

WindowCompat.getInsetsController(window, window.getDecorView())
    .setAppearanceLightStatusBars(false);

Perlindungan kolom sistem

Setelah aplikasi Anda menargetkan SDK 35 atau yang lebih tinggi, tampilan layar penuh akan diterapkan. Status bar sistem dan menu navigasi gestur bersifat transparan, tetapi menu navigasi tiga tombol bersifat tembus cahaya. Panggil enableEdgeToEdge agar kompatibel dengan versi lama.

Namun, setelan default sistem mungkin tidak berfungsi untuk semua kasus penggunaan. Lihat Panduan desain kolom sistem Android dan Desain layar penuh untuk menentukan apakah akan menggunakan kolom sistem transparan atau tembus cahaya.

Membuat kolom sistem transparan

Buat status bar transparan dengan menargetkan Android 15 (SDK 35) atau yang lebih tinggi atau dengan memanggil enableEdgeToEdge() dengan argumen default untuk versi sebelumnya.

Buat menu navigasi gestur transparan dengan menargetkan Android 15 atau yang lebih tinggi atau dengan memanggil enableEdgeToEdge() dengan argumen default untuk versi sebelumnya. Untuk menu navigasi tiga tombol, tetapkan Window.setNavigationBarContrastEnforced ke false. Jika tidak, scrim transparan akan diterapkan.

Membuat kolom sistem transparan

Untuk membuat status bar transparan, lakukan hal berikut:

  1. Update dependensi androidx-core ke 1.16.0-beta01 atau yang lebih tinggi
  2. Gabungkan tata letak XML Anda di androidx.core.view.insets.ProtectionLayout dan tetapkan ID.
  3. Akses ProtectionLayout secara terprogram untuk menetapkan perlindungan, dengan menentukan sisi dan GradientProtection untuk status bar.

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

findViewById<ProtectionLayout>(R.id.list_protection)
    .setProtections(
        listOf(
            GradientProtection(
                WindowInsetsCompat.Side.TOP,
                // Ideally, this is the pane's background color
                paneBackgroundColor
            )
        )
    )

Pastikan ColorInt yang diteruskan ke GradientProtection cocok dengan latar belakang konten. Misalnya, tata letak detail daftar yang ditampilkan di perangkat foldable mungkin memiliki GradientProtections yang berbeda dengan warna yang berbeda untuk panel daftar dan panel detail.

Gambar 1. Perlindungan gradien dengan berbagai warna.

Jangan membuat menu navigasi gestur transparan. Untuk membuat menu navigasi tiga tombol yang transparan, lakukan salah satu hal berikut:

  • Jika tata letak sudah digabungkan dalam ProtectionView, Anda dapat meneruskan ColorProtection atau GradientProtection tambahan ke metode setProtections. Sebelum melakukannya, pastikan window.isNavigationBarContrastEnforced = false.
  • Jika tidak, tetapkan window.isNavigationBarContrastEnforced = true.

Tips lainnya

Tips tambahan saat menangani inset.

Membuat konten scroll layar penuh

Pastikan item daftar terakhir tidak tertutup oleh kolom sistem di RecyclerView atau NestedScrollView dengan menangani inset dan menetapkan clipToPadding ke false.

Video berikut menampilkan RecyclerView dengan tampilan layar penuh dinonaktifkan (kiri) dan diaktifkan (kanan):

Lihat cuplikan kode di bagian Membuat daftar dinamis dengan RecyclerView untuk mengetahui contoh kode.

Membuat dialog layar penuh dari tepi ke tepi

Untuk membuat dialog layar penuh menjadi layar penuh, panggil enableEdgeToEdge di Dialog.

Kotlin

class MyAlertDialogFragment : DialogFragment() {
    override fun onStart(){
        super.onStart()
        dialog?.window?.let { WindowCompat.enableEdgeToEdge(it) }
    }
    ...
}

Java

public class MyAlertDialogFragment extends DialogFragment {
    @Override
    public void onStart() {
        super.onStart();
        Dialog dialog = getDialog();
        if (dialog != null) {
            Window window = dialog.getWindow();
            if (window != null) {
                WindowCompat.enableEdgeToEdge(window);
            }
        }
    }
    ...
}

Referensi lainnya

Lihat referensi berikut untuk mengetahui informasi selengkapnya tentang tampilan layar penuh.

Blog

Desain

Dokumentasi lainnya

Video