Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Layout   Part of Android Jetpack.

Layout menentukan struktur untuk antarmuka pengguna di aplikasi Anda, seperti di dalam aktivitas. Semua elemen pada layout dibuat menggunakan hierarki objek View dan ViewGroup. View biasanya menggambar sesuatu yang pengguna bisa melihat dan berinteraksi dengannya. Sedangkan ViewGroup adalah container yang tidak terlihat yang menentukan struktur layout untuk View dan objek ViewGroup lainnya, seperti yang ditampilkan pada gambar 1.

Gambar 1. Ilustrasi dari hierarki tampilan, yang mendefinisikan layout UI

Objek View biasanya disebut "widget" dan dapat menjadi salah satu dari banyak subclass, seperti Button atau TextView. Objek ViewGroup biasanya disebut "layout" yang bisa menjadi salah satu dari banyak tipe yang menyediakan struktur layout yang berbeda, seperti LinearLayout atau ConstraintLayout .

Anda dapat mendeklarasikan layout dengan dua cara:

  • Deklarasikan elemen UI dalam XML. Android menyediakan sebuah kosakata XML sederhana yang sesuai dengan kelas dan subkelas Tampilan, seperti halnya untuk widget dan layout.

    Anda juga dapat menggunakan Editor Layout untuk membuat layout XML menggunakan antarmuka seret dan letakkan.

  • Buat instance elemen layout saat waktu proses. Aplikasi Anda bisa membuat objek Tampilan dan ViewGroup (dan memanipulasi propertinya) melalui program.

Dengan mendeklarasikan UI pada XML, Anda dapat memisahkan presentasi aplikasi dari kode yang mengontrol perilakunya. Menggunakan file XML juga mempermudah dalam menyediakan layout yang berbeda untuk orientasi dan ukuran layar yang berbeda (dibahas lebih jauh pada Mendukung Ukuran Layar Berbeda).

Framework Android memberi Anda fleksibilitas untuk menggunakan salah satu atau kedua metode ini untuk membuat UI aplikasi. Misalnya, Anda bisa mendeklarasikan layout default aplikasi pada XML, kemudian memodifikasi layout saat runtime.

Tips:Untuk melakukan debug saat runtime, gunakan fitur Layout Inspector.

Tulis XML

Dengan menggunakan kosakata XML Android, Anda bisa mendesain secara cepat layout UI dan elemen layar yang dimuatnya, sama dengan cara membuat laman web dalam HTML — dengan serangkaian elemen tersarang.

Tiap file layout harus berisi persis satu elemen akar, yang harus berupa sebuah objek View atau ViewGroup. Setelah mendefinisikan elemen akar, Anda bisa menambahkan objek atau widget layout tambahan sebagai elemen anak untuk membangun hierarki View yang mendefinisikan layout Anda secara bertahap. Misalnya, inilah layout XML yang menggunakan LinearLayout vertikal untuk menyimpan TextView dan Button:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >
    <TextView android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Hello, I am a TextView" />
    <Button android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello, I am a Button" />
</LinearLayout>

Setelah Anda mendeklarasikan layout dalam XML, simpan file dengan ekstensi .xml, dalam direktori res/layout/ project Android, sehingga nanti bisa dikompilasi dengan benar.

Informasi selengkapnya tentang sintaks untuk file XML layout tersedia dalam dokumen Sumber Daya Layout.

Muat Sumber Daya XML

Saat mengompilasi aplikasi, masing-masing file layout XML akan dikompilasi dalam sumber daya View. Anda harus memuat sumber daya layout dari kode aplikasi Anda, pada implementasi callback Activity.onCreate(). Lakukan hal tersebut dengan memanggil setContentView(), memberikannya referensi ke sumber daya layout dalam bentuk: R.layout.layout_file_name. Misalnya, jika layout XML disimpan sebagai main_layout.xml, Anda akan memuatnya untuk Aktivitas Anda seperti:

Kotlin

fun onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main_layout)
}

Java

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);
}

Metode callback onCreate() dalam Aktivitas dipanggil oleh framework Android saat Aktivitas Anda dijalankan (lihat diskusi tentang daur hidup, dalam dokumen Aktivitas).

Atribut

Setiap objek Tampilan dan ViewGroup mendukung ragam atribut XML miliknya sendiri. Beberapa atribut bersifat khusus untuk objek Tampilan (misalnya, TextView mendukung atribut textSize), tetapi atribut ini juga diwarisi oleh objek Tampilan apa pun yang dapat memperluas kelas ini. Sebagian bersifat umum untuk semua objek Tampilan, karena diwarisi dari kelas Tampilan root (seperti atribut id). Dan, atribut lain dianggap sebagai "parameter layout" yaitu atribut yang menjelaskan orientasi layout tertentu dari objek Tampilan, seperti yang didefinisikan oleh objek ViewGroup induk dari objek itu.

ID

Setiap objek Tampilan mungkin memiliki ID integer yang terhubung dengannya, untuk mengidentifikasi tampilan secara unik di dalam struktur pohon. Saat aplikasi dikompilasi, ID ini dirujuk sebagai integer, tetapi ID-nya biasanya ditetapkan dalam file XML layout sebagai string, pada atribut id. Ini adalah atribut XML yang umum untuk semua objek Tampilan (didefinisikan oleh kelas View) dan Anda akan sering menggunakannya. Sintaks untuk ID, di dalam tag XML adalah:

android:id="@+id/my_button"

Simbol-at (@) pada awal string menunjukkan parser XML harus mengurai dan memperluas ID string selebihnya dan mengenalinya sebagai ID sumber daya. Simbol tanda tambah (+) berarti ini nama sumber daya baru yang harus dibuat dan ditambahkan ke sumber daya kita (dalam file R.java). Ada sejumlah sumber daya ID lain yang ditawarkan oleh framework Android. Saat merujuk pada sebuah ID sumber daya Android, Anda tidak memerlukan simbol tanda tambah, tetapi harus menambahkan namespace paket android, sehingga:

android:id="@android:id/empty"

Dengan namespace paket android yang tersedia, kita sekarang merujuk pada ID dari kelas sumber daya android.R, daripada kelas sumber daya lokal.

Untuk membuat tampilan dan merujuknya dari aplikasi, pola yang umum adalah:

  1. Mendefinisikan tampilan/widget dalam file layout dan memberinya ID unik:
    <Button android:id="@+id/my_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/my_button_text"/>
    
  2. Kemudian buat instance objek tampilan dan tangkap instance tersebut dari layout (biasanya dalam metode onCreate()):

    Kotlin

    val myButton: Button = findViewById(R.id.my_button)
    

    Java

    Button myButton = (Button) findViewById(R.id.my_button);
    

Menentukan ID untuk objek tampilan sifatnya penting saat membuat RelativeLayout. Dalam layout relatif, tampilan saudara bisa mendefinisikan layout secara relatif terhadap tampilan saudara lainnya, yang dirujuk melalui ID unik.

ID tidak perlu unik di seluruh pohon, namun harus unik di bagian pohon yang Anda cari (yang mungkin sering kali seluruh pohon, jadi lebih baik benar-benar unik jika memungkinkan).

Parameter Layout

Atribut layout XML bernama layout_something mendefinisikan parameter layout Tampilan yang cocok untuk ViewGroup tempatnya berada.

Setiap kelas ViewGroup mengimplementasikan kelas bertumpuk yang memperluas ViewGroup.LayoutParams. Subkelas ini berisi tipe properti yang mendefinisikan ukuran dan posisi masing-masing tampilan anak, sebagaimana mestinya untuk grup tampilan. Seperti yang bisa Anda lihat dalam gambar 2, grup tampilan induk mendefinisikan parameter layout untuk masing-masing tampilan anak (termasuk grup tampilan anak).

Gambar 2. Visualisasi hierarki tampilan dengan parameter layout yang dikaitkan dengan setiap tampilan.

Perhatikan bahwa setiap subkelas LayoutParams memiliki sintaksnya sendiri untuk menetapkan nilai-nilai. Tiap elemen anak harus mendefinisikan LayoutParams yang semestinya untuk induknya, meskipun elemen itu bisa juga mendefinisikan LayoutParams untuk anak-anaknya sendiri.

Semua grup tampilan berisi lebar dan tinggi (layout_width dan layout_height), dan masing-masing tampilan harus mendefinisikannya. Banyak LayoutParams yang juga menyertakan margin dan border opsional.

Anda bisa menetapkan lebar dan tinggi dengan ukuran persis, meskipun Anda mungkin tidak ingin sering-sering melakukannya. Seringnya, Anda akan menggunakan salah satu konstanta ini untuk mengatur lebar atau tinggi:

  • wrap_content memberi tahu tampilan Anda agar menyesuaikan sendiri ukurannya dengan dimensi yang dibutuhkan oleh kontennya.
  • match_parent memberi tahu tampilan Anda agar menjadi sebesar yang akan diperbolehkan oleh kelompok tampilan induknya.

Secara umum, menetapkan lebar dan tinggi layout dengan satuan mutlak seperti piksel tidak disarankan. Sebagai gantinya, menggunakan pengukuran relatif seperti satuan piksel yang tidak bergantung pada kerapatan (dp), wrap_content, atau match_parent, adalah sebuah pendekatan yang lebih baik, karena membantu memastikan bahwa aplikasi Anda akan ditampilkan dengan tepat pada berbagai ukuran layar perangkat. Tipe ukuran yang diterima didefinisikan dalam dokumen Resource Tersedia

Posisi Layout

Geometri tampilan adalah persegi panjang. Tampilan memiliki lokasi, yang dinyatakan sebagai pasangan koordinat kiri dan atas, dan dua dimensi, yang dinyatakan sebagai lebar dan tinggi. Satuan untuk lokasi dan dimensi adalah piksel.

Lokasi tampilan dapat diambil dengan memanggil metode getLeft() dan getTop(). Metode terdahulu menampilkan koordinat kiri atau X, persegi panjang yang merepresentasikan tampilan. Metode selanjutnya menampilkan koordinat atas atau Y, persegi panjang yang merepresentasikan tampilan. Kedua metode ini menampilkan lokasi tampilan relatif terhadap induknya. Misalnya, jika getLeft() menampilkan 20, berarti tampilan berlokasi 20 piksel ke kanan dari tepi kiri induk langsungnya.

Selain itu, beberapa metode praktis ditawarkan untuk menghindari komputasi yang tidak perlu, yakni getRight() dan getBottom(). Kedua metode ini menampilkan koordinat tepi kanan dan bawah persegi panjang yang merepresentasikan tampilan. Misalnya, memanggil getRight() serupa dengan komputasi berikut: getLeft() + getWidth().

Ukuran, Pengisi, dan Margin

Ukuran tampilan dinyatakan dengan lebar dan tinggi. Tampilan sebenarnya memiliki dua pasang nilai lebar dan tinggi.

Pasangan pertama disebut lebar terukur dan tinggi terukur. Dimensi ini mendefinisikan seberapa besar tampilan yang diinginkan dalam induknya. Dimensi terukur bisa diperoleh dengan memanggil getMeasuredWidth() dan getMeasuredHeight().

Pasangan kedua cukup disebut dengan lebar dan tinggi, atau kadang-kadang lebar penggambaran dan tinggi penggambaran. Dimensi-dimensi ini mendefinisikan ukuran tampilan sebenarnya pada layar, saat digambar dan setelah layout. Nilai-nilai ini mungkin, namun tidak harus, berbeda dengan lebar dan tinggi terukur. Lebar dan tinggi bisa diperoleh dengan memanggil getWidth() dan getHeight().

Untuk mengukur dimensinya, tampilan akan memperhitungkan pengisinya (padding). Pengisi dinyatakan dalam piksel untuk bagian kiri, atas, kanan, dan bawah tampilan. Pengisi bisa digunakan untuk meng-offset isi tampilan dengan piksel dalam jumlah tertentu. Misalnya, pengisi kiri sebesar 2 akan mendorong isi tampilan sebanyak 2 piksel ke kanan dari tepi kiri. Pengisi bisa diatur menggunakan metodesetPadding(int, int, int, int) dan diketahui dengan memanggil getPaddingLeft(), getPaddingTop(), getPaddingRight(), dan getPaddingBottom().

Meskipun bisa mendefinisikan pengisi, tampilan tidak menyediakan dukungan untuk margin. Akan tetapi, grup tampilan menyediakan dukungan tersebut. Lihat ViewGroup dan ViewGroup.MarginLayoutParams untuk informasi lebih jauh.

Untuk informasi selengkapnya tentang dimensi, lihat Nilai-Nilai Dimensi.

Layout Umum

Tiap subkelas dari kelas ViewGroup menyediakan cara unik untuk menampilkan tampilan yang Anda tumpuk di dalamnya. Di bawah ini adalah beberapa tipe layout lebih umum yang dibuat ke dalam platform Android.

Catatan: Walaupun Anda bisa menumpuk satu atau beberapa layout dalam layout lain untuk mendapatkan desain UI, Anda harus berusaha menjaga hierarki layout sedangkal mungkin. Layout Anda akan digambar lebih cepat jika memiliki layout bertumpuk yang lebih sedikit (hierarki tampilan yang melebar lebih baik daripada hierarki tampilan yang dalam).

Layout Linier

Layout yang mengatur anak-anaknya menjadi satu baris horizontal atau vertikal. Layout ini akan membuat scrollbar jika panjang jendela melebihi panjang layar.

Layout Relatif

Memungkinkan Anda menentukan lokasi objek anak relatif terhadap satu sama lain (anak A di kiri anak B) atau terhadap induk (disejajarkan dengan atas induknya).

Tampilan Web

Menampilkan laman web.

Membangun Layout dengan Adaptor

Jika isi layout bersifat dinamis atau tidak ditentukan sebelumnya, Anda bisa menggunakan layout yang menjadi subkelas AdapterView untuk mengisi layout dengan tampilan saat runtime. Subkelas dari kelas AdapterView menggunakan Adapter untuk menautkan data ke layoutnya. Adapter berfungsi sebagai penghubung antara sumber data dan layout AdapterViewAdapter mengambil data (dari suatu sumber seperti larik (array) atau kueri database) dan mengubah setiap entri menjadi tampilan yang bisa ditambahkan ke dalam layout AdapterView.

Layout umum yang didukung oleh adaptor meliputi:

Tampilan Daftar

Menampilkan daftar kolom tunggal yang bergulir.

Tampilan Petak

Menampilkan petak kolom dan baris yang bergulir.

Mengisi tampilan adaptor dengan data

Anda bisa mengisi AdapterView seperti ListView atau GridView dengan menautkan instance AdapterView ke Adapter, yang akan mengambil data dari sumber eksternal dan membuat View yang mewakili setiap entri data.

Android menyediakan beberapa subkelas Adapter yang berguna untuk mengambil berbagai jenis data dan membuat tampilan untuk AdapterView. Dua adapter yang paling umum adalah:

ArrayAdapter
Gunakan adaptor ini bila sumber data Anda berupa larik. Secara default, ArrayAdapter akan membuat tampilan untuk setiap elemen larik dengan memanggil toString() pada setiap elemen serta menempatkan materinya dalam TextView.

Misalnya, jika Anda memiliki satu larik string yang ingin ditampilkan dalam ListView, lakukan inisialisasi ArrayAdapter baru dengan konstruktor untuk menetapkan layout setiap string dan larik string:

Kotlin

val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray)

Java

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, myStringArray);

Argumen-argumen untuk konstruktor ini adalah:

  • Context Aplikasi Anda
  • Layout yang berisi TextView untuk tiap string dalam larik
  • Larik string

Kemudian cukup panggil setAdapter() pada ListViewAnda:

Kotlin

val listView: ListView = findViewById(R.id.listview)
listView.adapter = adapter

Java

ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);

Untuk menyesuaikan penampilan setiap item, Anda bisa mengganti metode toString() bagi objek dalam larik Anda. Atau, untuk membuat tampilan setiap elemen selain TextView (misalnya, jika Anda menginginkan ImageView untuk setiap item larik), perluas kelas ArrayAdapter dan ganti getView() untuk menampilkan tipe tampilan yang Anda inginkan bagi setiap item.

SimpleCursorAdapter
Gunakan adapter ini jika data Anda berasal dari Cursor. Saat menggunakan SimpleCursorAdapter, Anda harus menentukan layout yang akan digunakan untuk tiap baris dalam Cursor dan di kolom mana di Cursor harus memasukkan tampilan layout. Misalnya, jika Anda ingin membuat daftar nama orang dan nomor ponsel, Anda bisa melakukan kueri yang menampilkan Cursor berisi satu baris untuk setiap orang serta kolom-kolom untuk nama dannomor. Selanjutnya Anda membuat larik string yang menetapkan kolom dari Cursor yang Anda inginkan dalam layout untuk setiap hasil dan larik integer yang menetapkan tampilan yang harus ditempatkan oleh masing-masing kolom:

Kotlin

val fromColumns = arrayOf(ContactsContract.Data.DISPLAY_NAME,
                          ContactsContract.CommonDataKinds.Phone.NUMBER)
val toViews = intArrayOf(R.id.display_name, R.id.phone_number)

Java

String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME,
                        ContactsContract.CommonDataKinds.Phone.NUMBER};
int[] toViews = {R.id.display_name, R.id.phone_number};

Jika Anda membuat instance SimpleCursorAdapter, teruskan layout yang akan digunakan untuk setiap hasil, Cursor yang berisi hasil tersebut, dan dua larik ini:

Kotlin

val adapter = SimpleCursorAdapter(this,
        R.layout.person_name_and_number, cursor, fromColumns, toViews, 0)
val listView = getListView()
listView.adapter = adapter

Java

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
        R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);
ListView listView = getListView();
listView.setAdapter(adapter);

SimpleCursorAdapter Kemudian membuat tampilan untuk setiap baris dalam Cursor menggunakan layout yang disediakan dengan memasukkan setiap item fromColumns ke dalam tampilan toViews yang bersangkutan.

.

Jika, selama berjalannya aplikasi, Anda mengubah data yang mendasarinya, yang dibaca oleh adapter, Anda harus memanggil notifyDataSetChanged(). Hal ini akan memberi tahu tampilan yang bersangkutan bahwa data telah berubah dan tampilan harus melakukan penyegaran sendiri.

Menangani kejadian klik

Anda bisa merespons peristiwa klik pada setiap item dalam AdapterView dengan menerapkan antarmuka AdapterView.OnItemClickListener. Sebagai contoh:

Kotlin

listView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
    // Do something in response to the click
}

Java

// Create a message handling object as an anonymous class.
private OnItemClickListener messageClickedHandler = new OnItemClickListener() {
    public void onItemClick(AdapterView parent, View v, int position, long id) {
        // Do something in response to the click
    }
};

listView.setOnItemClickListener(messageClickedHandler);

Sumber daya tambahan

Layout digunakan pada aplikasi demo Sunflower.