Desain responsif/adaptif dengan tampilan

Mencoba cara Compose
Jetpack Compose adalah toolkit UI yang direkomendasikan untuk Android. Pelajari cara menggunakan tata letak responsif di Compose.

Tata letak responsif/adaptif memberikan pengalaman pengguna yang dioptimalkan, apa pun ukuran layar pengguna. Terapkan tata letak responsif/adaptif agar aplikasi berbasis tampilan Anda dapat mendukung semua ukuran, orientasi, dan konfigurasi layar, termasuk konfigurasi yang dapat diubah ukurannya seperti mode multi-aplikasi.

Desain responsif

Langkah pertama dalam mendukung berbagai faktor bentuk perangkat adalah membuat tata letak yang responsif terhadap variasi jumlah ruang tampilan yang tersedia untuk aplikasi Anda.

ConstraintLayout

Cara terbaik untuk membuat tata letak responsif adalah menggunakan ConstraintLayout sebagai tata letak dasar untuk UI Anda. ConstraintLayout memungkinkan Anda menentukan posisi dan ukuran setiap tampilan berdasarkan hubungan spasial dengan tampilan lainnya dalam tata letak. Semua tampilan kemudian dapat berpindah dan mengubah ukuran bersama-sama seiring perubahan ruang tampilan.

Cara termudah untuk membuat tata letak dengan ConstraintLayout adalah menggunakan Layout Editor di Android Studio. Layout Editor memungkinkan Anda menarik tampilan baru ke tata letak, menerapkan batasan relatif ke tampilan induk dan tampilan setara, serta menyetel properti tampilan—semuanya tanpa perlu mengedit file XML apa pun secara manual.

Gambar 3. Layout Editor di Android Studio menampilkan ConstraintLayout.

Untuk informasi selengkapnya, lihat Mem-build UI yang Responsif Dengan ConstraintLayout.

Lebar dan tinggi responsif

Untuk memastikan tata letak Anda responsif terhadap berbagai ukuran tampilan, gunakan wrap_content, match_parent, atau 0dp (match constraint) untuk lebar dan tinggi komponen tampilan, bukan nilai hard code:

  • wrap_content: Tampilan menetapkan ukurannya agar sesuai dengan konten yang dimuat tampilan.
  • match_parent: Tampilan diperluas seluas mungkin dalam tampilan induk.
  • 0dp (match constraint): Di ConstraintLayout, mirip dengan match_parent. Tampilan menggunakan semua ruang yang tersedia dalam batasan tampilan.

Contoh:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/lorem_ipsum" />

Gambar 4 menunjukkan bagaimana lebar dan tinggi TextView disesuaikan ketika lebar layar berubah dengan orientasi perangkat.

Gambar 4. TextView responsif.

TextView menetapkan lebarnya untuk mengisi semua ruang yang tersedia (match_parent) dan tingginya ke ruang yang dibutuhkan oleh tinggi teks yang dimuat (wrap_content), yang memungkinkan tampilan untuk beradaptasi dengan berbagai dimensi tampilan dan jumlah teks yang berbeda.

Jika menggunakan LinearLayout, Anda juga dapat memperluas tampilan turunan berdasarkan bobot tata letak sehingga tampilan tersebut akan mengisi ruang yang tersedia secara proporsional. Namun, menggunakan bobot dalam LinearLayout bertingkat mengharuskan sistem melakukan beberapa penerusan tata letak untuk menentukan ukuran setiap tampilan, yang memperlambat performa UI.

ConstraintLayout dapat membuat hampir semua tata letak dengan LinearLayout tanpa memengaruhi performa, jadi konversikan LinearLayout bertingkat menjadi ConstraintLayout. Kemudian, Anda dapat menentukan tata letak berbobot dengan rantai batasan.

Desain adaptif

Tata letak aplikasi harus selalu responsif terhadap berbagai ukuran tampilan. Namun, tata letak responsif pun tidak dapat memberikan pengalaman pengguna terbaik di setiap perangkat atau tampilan mode multi-aplikasi. Misalnya, UI yang didesain untuk ponsel mungkin tidak memberikan pengalaman pengguna yang optimal di tablet. Desain adaptif menyediakan tata letak alternatif yang telah dioptimalkan untuk berbagai dimensi tampilan.

SlidingPaneLayout untuk UI daftar-detail

UI daftar-detail biasanya memberikan pengalaman pengguna yang berbeda di layar dengan ukuran yang berbeda pula. Di layar besar, panel daftar dan detail biasanya berdampingan. Saat item dalam daftar dipilih, informasi item akan ditampilkan di panel detail tanpa mengubah UI—dua panel tetap berdampingan. Namun, pada layar berukuran kecil, dua panel ditampilkan secara terpisah, setiap panel menempati seluruh area tampilan. Jika item di panel daftar dipilih, panel detail (berisi informasi item yang dipilih) akan menggantikan panel daftar. Navigasi kembali menggantikan panel detail dengan daftar.

SlidingPaneLayout mengelola logika untuk menentukan manakah dari kedua pengalaman pengguna tersebut yang sesuai untuk ukuran jendela saat ini:

<?xml version="1.0" encoding="utf-8"?>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="start" />

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:defaultNavHost="true"
        app:navGraph="@navigation/item_navigation" />

</androidx.slidingpanelayout.widget.SlidingPaneLayout>

Atribut layout_width dan layout_weight dari dua tampilan yang terdapat di SlidingPaneLayout menentukan perilaku SlidingPaneLayout. Pada contoh, jika jendela cukup besar (minimal 580 dp) untuk menampilkan kedua tampilan, panel akan ditampilkan secara berdampingan. Namun, jika lebar jendela lebih kecil dari 580 dp, panel akan bergeser satu sama lain untuk menempati satu jendela aplikasi secara keseluruhan.

Jika lebar jendela lebih besar dari total lebar minimum yang ditentukan (580 dp), nilai layout_weight dapat digunakan untuk mengukur kedua panel secara proporsional. Dalam contoh, panel daftar selalu memiliki lebar 280 dp karena tidak memiliki bobot. Namun, panel detail selalu mengisi ruang horizontal di atas 580 dp karena setelan layout_weight tampilan.

Resource tata letak alternatif

Untuk menyesuaikan desain UI Anda dengan berbagai ukuran layar, gunakan tata letak alternatif yang diidentifikasi oleh penentu resource.

Gambar 5. Aplikasi yang sama menggunakan tata letak yang berbeda untuk ukuran tampilan yang berbeda.

Anda dapat menyediakan tata letak adaptif khusus layar dengan membuat direktori res/layout/ tambahan di kode sumber aplikasi Anda. Buat direktori untuk setiap konfigurasi layar yang memerlukan tata letak berbeda. Kemudian, tambahkan pengontrol kualitas konfigurasi layar ke nama direktori layout (misalnya, layout-w600dp untuk layar yang memiliki lebar yang tersedia sebesar 600 dp).

Pengontrol kualitas konfigurasi mewakili ruang tampilan yang terlihat dan tersedia untuk UI aplikasi Anda. Sistem memperhitungkan setiap dekorasi sistem (seperti menu navigasi) dan perubahan konfigurasi jendela (seperti mode multi-aplikasi) saat memilih tata letak untuk aplikasi Anda.

Untuk membuat tata letak alternatif di Android Studio, lihat Menggunakan varian tata letak untuk mengoptimalkan berbagai layar di Mengembangkan UI dengan View.

Penentu lebar terkecil

Penentu ukuran layar lebar terkecil memungkinkan Anda menyediakan tata letak alternatif untuk layar dengan lebar minimum yang diukur dalam piksel kepadatan mandiri (dp).

Dengan mendeskripsikan ukuran layar sebagai ukuran dp, Android memungkinkan Anda membuat tata letak yang didesain untuk dimensi layar tertentu tanpa memperhatikan kepadatan piksel yang berbeda.

Misalnya, Anda dapat membuat tata letak bernama main_activity yang dioptimalkan untuk ponsel dan tablet dengan membuat versi file yang berbeda di direktori yang berbeda:

res/layout/main_activity.xml           # For phones (smaller than 600dp smallest width)
res/layout-sw600dp/main_activity.xml   # For 7" tablets (600dp wide or wider)

Penentu lebar terkecil menentukan sisi terkecil dari dua sisi layar, terlepas dari orientasi perangkat yang sedang diterapkan. Jadi, ini adalah cara untuk menentukan ukuran layar keseluruhan yang tersedia untuk tata letak Anda.

Berikut adalah bagaimana nilai lebar terkecil lainnya menyesuaikan ukuran layar umum:

  • 320 dp: Layar ponsel kecil (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, dll.)
  • 480 dp: Layar ponsel besar ~5" (480x800 mdpi)
  • 600 dp: tablet 7" (600x1024 mdpi)
  • 720 dp: tablet 10" (720x1280 mdpi, 800x1280 mdpi, dll.)

Gambar berikut memberikan gambaran yang lebih mendetail tentang bagaimana lebar dp layar yang berbeda sesuai dengan berbagai ukuran dan orientasi layar.

Gambar 6. Titik henti lebar sementara yang dianjurkan untuk mendukung berbagai ukuran layar.

Nilai untuk penentu lebar terkecil adalah dp, karena yang penting adalah jumlah ruang tampilan yang tersedia setelah sistem memperhitungkan kepadatan piksel (bukan resolusi piksel mentah).

Ukuran yang Anda tentukan menggunakan penentu resource seperti lebar terkecil bukanlah ukuran layar sebenarnya. Ukuran ini menentukan lebar atau tinggi dalam unit dp yang tersedia untuk jendela aplikasi Anda. Sistem Android mungkin menggunakan sebagian layar untuk UI sistem (seperti kolom sistem di bagian bawah layar atau status bar di bagian atas), sehingga sebagian layar mungkin tidak tersedia untuk tata letak Anda. Jika digunakan dalam mode multi-aplikasi, aplikasi hanya dapat mengakses ukuran jendela yang berisi aplikasi. Jika ukuran jendela diubah, perubahan konfigurasi akan terpicu dengan ukuran jendela yang baru, yang memungkinkan sistem memilih file tata letak yang sesuai. Jadi, ukuran penentu resource yang Anda deklarasikan hanya boleh menentukan ruang yang dibutuhkan aplikasi. Sistem memperhitungkan setiap ruang yang digunakan oleh UI sistem saat menyediakan ruang untuk tata letak Anda.

Penentu lebar yang tersedia

Daripada mengubah tata letak berdasarkan lebar terkecil layar, Anda mungkin perlu mengubah tata letak berdasarkan seberapa besar lebar atau tinggi yang tersedia. Misalnya, Anda mungkin ingin menggunakan tata letak dua panel setiap kali layar menyediakan lebar minimal 600 dp, yang dapat berubah bergantung pada apakah perangkat dalam orientasi lanskap atau potret. Dalam hal ini, Anda harus menggunakan penentu lebar yang tersedia seperti berikut:

res/layout/main_activity.xml         # For phones (smaller than 600dp available width)
res/layout-w600dp/main_activity.xml  # For 7" tablets or any screen with 600dp available width
                                     # (possibly landscape phones)

Jika tinggi yang tersedia tidak sesuai untuk aplikasi, Anda dapat menggunakan penentu tinggi yang tersedia. Misalnya, layout-h600dp untuk layar yang berukuran minimal 600 dp.

Penentu orientasi

Meskipun Anda mungkin dapat mendukung semua variasi ukuran hanya dengan kombinasi penentu lebar terkecil dan lebar yang tersedia, Anda juga dapat mengubah pengalaman pengguna saat pengguna beralih antara orientasi potret dan lanskap.

Untuk itu, Anda dapat menambahkan penentu port atau land ke nama direktori tata letak. Pastikan penentu orientasi muncul setelah penentu ukuran. Contoh:

res/layout/main_activity.xml                # For phones
res/layout-land/main_activity.xml           # For phones in landscape
res/layout-sw600dp/main_activity.xml        # For 7" tablets
res/layout-sw600dp-land/main_activity.xml   # For 7" tablets in landscape

Untuk informasi selengkapnya tentang semua pengontrol kualitas konfigurasi layar, lihat Ringkasan resource aplikasi.

Class ukuran jendela

Class ukuran jendela adalah titik henti sementara area pandang yang membantu Anda membuat tata letak adaptif. Titik henti sementara mengidentifikasi area tampilan yang tersedia untuk aplikasi Anda sebagai rapat, sedang, atau diperluas. Lebar dan tinggi ditentukan secara terpisah, sehingga aplikasi Anda selalu memiliki class ukuran jendela untuk lebar dan class ukuran jendela untuk tinggi.

Untuk menerapkan tata letak adaptif secara terprogram, lakukan hal berikut:

  • Membuat resource tata letak berdasarkan titik henti sementara class ukuran jendela
  • Hitung class ukuran jendela lebar dan tinggi aplikasi Anda menggunakan fungsi WindowSizeClass#compute() dari library Jetpack WindowManager
  • Meng-inflate resource tata letak untuk class ukuran jendela saat ini

Untuk mengetahui informasi selengkapnya, lihat Class ukuran jendela.

Komponen UI modular menggunakan fragmen

Saat mendesain aplikasi untuk berbagai ukuran layar, gunakan fragmen untuk mengekstrak logika UI ke dalam komponen terpisah guna memastikan Anda tidak perlu menduplikasi perilaku UI di seluruh aktivitas. Kemudian, Anda dapat menggabungkan fragmen untuk membuat tata letak multipanel di perangkat layar besar, atau menempatkan fragmen dalam aktivitas terpisah di perangkat layar kecil.

Misalnya, pola daftar-detail (lihat SlidingPaneLayout di atas) dapat diterapkan dengan satu fragmen yang berisi daftar dan fragmen lain yang berisi detail item daftar. Di perangkat layar besar, fragmen dapat ditampilkan berdampingan; di layar kecil, fragmen ditampilkan satu per satu dan memenuhi layar.

Untuk mempelajari lebih lanjut, lihat ringkasan Fragmen.

Penyematan aktivitas

Jika aplikasi Anda terdiri dari beberapa aktivitas, penyematan aktivitas memungkinkan Anda membuat UI adaptif dengan mudah.

Penyematan aktivitas menampilkan beberapa aktivitas atau beberapa instance aktivitas yang sama secara bersamaan dalam jendela tugas aplikasi. Pada perangkat layar besar, aktivitas dapat ditampilkan secara berdampingan; pada perangkat layar kecil, aktivitas ditumpuk di atas aktivitas lain.

Anda menentukan cara aplikasi menampilkan aktivitasnya dengan membuat file konfigurasi XML yang digunakan sistem untuk menentukan presentasi yang sesuai berdasarkan ukuran tampilan. Atau, Anda dapat melakukan panggilan Jetpack WindowManager API.

Penyematan aktivitas mendukung perubahan orientasi perangkat dan perangkat foldable, menumpuk dan membongkar aktivitas saat perangkat diputar atau dilipat dan dibentangkan.

Untuk informasi selengkapnya, lihat Penyematan aktivitas.

Ukuran layar dan rasio lebar tinggi

Uji aplikasi Anda pada berbagai ukuran layar dan rasio lebar tinggi untuk memastikan UI diskalakan dengan benar.

Android 10 (API level 29) dan yang lebih baru mendukung berbagai rasio lebar tinggi. Faktor bentuk perangkat foldable dapat bervariasi mulai dari layar tinggi dan sempit, seperti 21:9 saat dilipat, hingga rasio lebar tinggi persegi 1:1 saat dibentangkan.

Untuk memastikan kompatibilitas dengan perangkat sebanyak mungkin, uji aplikasi Anda menggunakan sebanyak mungkin rasio lebar tinggi layar berikut:

Gambar 7. Beragam rasio lebar tinggi layar.

Jika tidak memiliki akses ke perangkat untuk semua ukuran layar yang berbeda yang ingin diuji, Anda dapat menggunakan Android Emulator untuk mengemulasikan hampir semua ukuran layar.

Jika Anda lebih memilih untuk mengujinya di perangkat yang sebenarnya tetapi tidak memilikinya, Anda dapat menggunakan Firebase Test Lab untuk mengakses perangkat di pusat data Google.

Referensi lainnya