Tata letak Bagian dari Android Jetpack.
Tata letak menentukan struktur dari antarmuka pengguna di aplikasi Anda, seperti di dalam aktivitas.
Semua elemen pada tata letak dibuat menggunakan hierarki objek View
dan
ViewGroup
. View
biasanya
menggambar sesuatu yang terlihat, dan pengguna dapat berinteraksi dengannya. Sedangkan ViewGroup
adalah
container tak terlihat yang menentukan struktur tata letak bagi View
dan objek
ViewGroup
lainnya, seperti yang ditampilkan pada gambar 1.

Gambar 1. Ilustrasi dari hierarki tampilan, yang mendefinisikan tata letak UI
Objek View
yang biasanya disebut "widget" dapat berupa salah satu dari banyak
subclass, seperti Button
atau TextView
. Objek
ViewGroup
yang biasanya disebut "tata letak" dapat berupa salah satu dari banyak jenis yang
menyediakan berbagai struktur tata letak, seperti LinearLayout
atau
ConstraintLayout
.
Anda dapat mendeklarasikan tata letak dengan dua cara:
- Deklarasikan elemen UI dalam XML. Android menyediakan kosakata XML
sederhana yang sesuai dengan class dan subclass Tampilan, seperti halnya untuk widget dan
tata letak.
Anda juga dapat menggunakan Layout Editor di Android Studio untuk membuat tata letak XML menggunakan antarmuka tarik lalu lepas.
- Buat instance elemen tata letak pada saat runtime. Aplikasi Anda dapat membuat objek Tampilan dan ViewGroup (serta memanipulasi propertinya) secara terprogram.
Dengan mendeklarasikan UI pada XML, Anda dapat memisahkan presentasi aplikasi dari kode yang mengontrol perilakunya. Menggunakan file XML juga mempermudah dalam menyediakan berbagai tata letak untuk orientasi dan ukuran layar yang berbeda (yang dibahas lebih jauh di Mendukung Berbagai Ukuran Layar).
Framework Android memberi Anda fleksibilitas untuk menggunakan salah satu atau kedua metode ini untuk membuat UI aplikasi Anda. Misalnya, Anda dapat mendeklarasikan tata letak default aplikasi pada XML, kemudian memodifikasinya saat runtime.
Tips: Untuk melakukan debug saat runtime, gunakan alat Layout Inspector.
Menulis XML
Dengan menggunakan kosakata XML Android, Anda dapat mendesain tata letak UI dan elemen layar yang dimuatnya secara cepat, sama dengan cara membuat halaman web dalam HTML — dengan serangkaian elemen bertumpuk.
Tiap file tata letak harus berisi persis satu elemen root, yang harus berupa sebuah objek Tampilan atau ViewGroup. Setelah mendefinisikan elemen root, Anda dapat menambahkan objek atau widget tata letak tambahan sebagai elemen turunan untuk secara bertahap membangun hierarki Tampilan yang mendefinisikan tata letak Anda. Sebagai contoh, berikut adalah tata letak 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 tata letak dalam XML, simpan file dengan ekstensi .xml
,
dalam direktori res/layout/
project Android, sehingga nanti bisa dikompilasi dengan benar.
Informasi selengkapnya tentang sintaksis untuk file XML tata letak tersedia dalam dokumen Resource Tata Letak.
Memuat Sumber Daya XML
Saat mengompilasi aplikasi, masing-masing file tata letak XML akan dikompilasikan menjadi
resource View
. Anda harus memuat resource tata letak dari kode aplikasi, pada
implementasi callback Activity.onCreate()
.
Lakukan hal tersebut dengan memanggil
,
yang akan meluluskan referensi ke resource tata letak dalam bentuk:
setContentView()
R.layout.layout_file_name
.
Misalnya, jika tata letak XML disimpan sebagai main_layout.xml
, Anda akan memuatnya
untuk Aktivitas Anda seperti berikut:
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 siklus proses, 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 class ini.
Sebagian bersifat umum untuk semua objek Tampilan, karena diwarisi dari class Tampilan root (seperti
atribut id
). Lalu, atribut lain dianggap sebagai "parameter tata letak," yang merupakan
atribut yang mendeskripsikan orientasi tata letak tertentu dari objek Tampilan, seperti yang didefinisikan oleh objek
objek ViewGroup induk.
ID
Setiap objek Tampilan mungkin memiliki ID bilangan bulat yang terhubung dengannya, untuk mengidentifikasi Tampilan secara unik di dalam struktur pohon.
Saat aplikasi dikompilasi, ID tersebut dirujuk sebagai bilangan bulat, tetapi biasanya ID
ditetapkan dalam file XML tata letak sebagai string, pada atribut id
.
Ini adalah atribut XML yang umum untuk semua objek Tampilan
(didefinisikan oleh class View
) dan Anda akan sering menggunakannya.
Sintaksis untuk ID, di dalam tag XML adalah:
android:id="@+id/my_button"
Simbol-at (@) pada awal string menunjukkan bahwa parser XML harus mengurai dan memperluas ID string lainnya
dan mengenalinya sebagai ID resource. Simbol tanda tambah (+) berarti ini nama resource baru yang harus
dibuat dan ditambahkan ke resource kita (dalam file R.java
). Ada sejumlah resource ID lain yang ditawarkan
oleh framework Android. Saat merujuk pada sebuah ID resource Android, Anda tidak memerlukan simbol
tanda tambah, tetapi harus menambahkan namespace paket android
, seperti berikut:
android:id="@android:id/empty"
Dengan namespace paket android
yang sudah ditempatkan, kita sekarang merujuk pada ID dari class resource android.R
daripada class resource lokal.
Untuk membuat tampilan dan merujuknya dari aplikasi, pola yang umum adalah:
- Mendefinisikan tampilan/widget dalam file tata letak 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"/>
- Kemudian buat instance objek tampilan dan tangkap instance tersebut dari tata letak
(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 adalah hal yang penting saat membuat RelativeLayout
.
Dalam tata letak relatif, tampilan saudara dapat mendefinisikan tata letak secara relatif terhadap tampilan saudara lainnya,
yang dirujuk melalui ID unik.
ID tidak perlu unik di seluruh pohon, tetapi harus unik di bagian pohon yang Anda cari (yang mungkin sering kali seluruh pohon, jadi lebih baik benar-benar unik jika memungkinkan).
Catatan: Dengan Android Studio 3.6 dan yang lebih baru, fitur
view binding dapat menggantikan panggilan
findViewById()
dan memberikan keamanan jenis waktu kompilasi untuk
kode yang berinteraksi dengan tampilan. Pertimbangkan untuk menggunakan view binding, bukan
findViewById()
.
Parameter Tata Letak
Atribut tata letak XML bernama layout_something
mendefinisikan
parameter tata letak Tampilan yang cocok untuk ViewGroup tempatnya berada.
Setiap class ViewGroup mengimplementasikan class bertumpuk yang memperluas ViewGroup.LayoutParams
. Subclass ini
berisi tipe properti yang mendefinisikan ukuran dan posisi masing-masing tampilan turunan, sebagaimana
mestinya untuk kelompok tampilan. Seperti yang bisa dilihat dalam gambar 2, kelompok tampilan induk
mendefinisikan parameter tata letak untuk masing-masing tampilan turunan (termasuk kelompok tampilan turunan).

Gambar 2. Visualisasi hierarki tampilan dengan parameter tata letak yang dikaitkan dengan tiap tampilan
Perhatikan bahwa setiap subclass LayoutParams memiliki sintaksisnya sendiri untuk menyetel nilai-nilai. Tiap elemen turunan harus mendefinisikan LayoutParams yang semestinya untuk induknya, meskipun elemen itu bisa juga mendefinisikan LayoutParams untuk turunannya sendiri.
Semua kelompok tampilan berisi lebar dan tinggi (layout_width
dan
layout_height
), dan setiap tampilan harus mendefinisikannya. Banyak
LayoutParams yang juga menyertakan margin dan batas opsional.
Anda dapat menentukan lebar dan tinggi dengan ukuran persis, meskipun Anda mungkin tidak ingin sering-sering melakukannya. Anda akan lebih sering menggunakan salah satu konstanta ini untuk mengatur lebar atau tinggi:
- wrap_content memberi tahu tampilan agar menyesuaikan ukuran dengan dimensi yang dibutuhkan oleh isinya.
- match_parent memberi tahu tampilan agar menjadi sebesar mungkin sesuai yang diizinkan kelompok tampilan induknya.
Secara umum, menetapkan lebar dan tinggi tata letak menggunakan satuan mutlak seperti piksel tidak direkomendasikan. Sebagai gantinya, penggunaan pengukuran relatif seperti unit piksel kepadatan mandiri (dp), wrap_content, atau match_parent, adalah pendekatan yang lebih baik, karena membantu memastikan bahwa aplikasi Anda akan ditampilkan dengan benar di berbagai ukuran layar perangkat. Tipe ukuran yang diterima didefinisikan dalam dokumen Resource yang Tersedia.
Posisi Tata Letak
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 pertama menampilkan koordinat kiri atau X,
koordinat dari persegi panjang akan mewakili tampilan. Metode selanjutnya menampilkan
koordinat atas atau Y, koordinat dari persegi panjang akan mewakili 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 mewakili 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 disebut dengan lebar dan tinggi, atau
terkadang lebar gambar dan tinggi gambar. Dimensi
ini mendefinisikan ukuran tampilan sebenarnya pada layar, saat digambar dan
setelah tata letak. Nilai-nilai ini mungkin, tetapi 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. Pengisi
dinyatakan dalam piksel untuk bagian kiri, atas, kanan, dan bawah tampilan.
Pengisi dapat digunakan untuk menyesuaikan isi tampilan dengan piksel dalam
jumlah tertentu. Misalnya, pengisi kiri dengan nilai 2 akan mendorong isi tampilan sebanyak
2 piksel ke kanan dari tepi kiri. Pengisi dapat diatur menggunakan
metode setPadding(int, int, int, int)
dan dikueri dengan memanggil
getPaddingLeft()
, getPaddingTop()
,
getPaddingRight()
dan getPaddingBottom()
.
Meskipun bisa mendefinisikan pengisi, tampilan tidak menyediakan dukungan untuk
margin. Akan tetapi, kelompok tampilan menyediakan dukungan tersebut. Lihat
ViewGroup
dan
ViewGroup.MarginLayoutParams
untuk informasi lebih lanjut.
Untuk informasi dimensi selengkapnya, lihat Nilai Dimensi.
Tata Letak Umum
Setiap subclass dari class ViewGroup
menyediakan cara unik untuk menampilkan
tampilan yang Anda tumpuk di dalamnya. Di bawah ini adalah beberapa tipe tata letak yang lebih umum yang dibuat
ke dalam platform Android.
Catatan: Walaupun Anda dapat menumpuk satu atau beberapa tata letak dalam tata letak lain untuk mendapatkan desain UI, Anda harus berusaha menjaga hierarki tata letak sedangkal mungkin. Tata letak Anda akan digambar lebih cepat jika memiliki tata letak bertumpuk yang lebih sedikit (hierarki tampilan yang lebar lebih baik daripada hierarki tampilan yang dalam).
Tata Letak Linear

Tata letak yang mengatur turunannya menjadi satu baris horizontal atau vertikal. Tata letak ini akan membuat scrollbar jika panjang jendela melebihi panjang layar.
Tata Letak Relatif

Memungkinkan Anda menentukan lokasi objek turunan relatif terhadap satu sama lain (turunan A di kiri turunan B) atau terhadap induk (diratakan dengan atas induknya).
Membangun Tata Letak dengan Adaptor
Jika isi tata letak bersifat dinamis atau tidak ditentukan sebelumnya, Anda dapat menggunakan tata letak
yang menjadi subclass AdapterView
untuk mengisi tata letak dengan tampilan saat runtime. Subclass dari class AdapterView
menggunakan Adapter
untuk
mengikat data ke tata letaknya. Adapter
berfungsi sebagai penghubung antara sumber
data dan tata letak AdapterView
. Adapter
mengambil data (dari sumber seperti array atau kueri database) dan mengonversi setiap entri
menjadi tampilan yang dapat ditambahkan ke dalam tata letak AdapterView
.
Tata letak umum yang didukung oleh adaptor meliputi:
Mengisi tampilan adaptor dengan data
Anda dapat 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 subclass Adapter
yang berguna untuk
mengambil berbagai jenis data dan membuat tampilan untuk AdapterView
. Dua
adaptor yang paling umum adalah:
ArrayAdapter
- Gunakan adaptor ini bila sumber data berupa array. Secara default,
ArrayAdapter
akan membuat tampilan untuk setiap elemen array dengan memanggiltoString()
pada setiap elemen serta menempatkan materinya dalamTextView
.Misalnya, jika Anda memiliki satu array string yang ingin ditampilkan dalam
ListView
, lakukan inisialisasiArrayAdapter
baru dengan konstruktor untuk menetapkan tata letak setiap string dan array 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:
Lalu, cukup panggil
setAdapter()
padaListView
Anda: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 dapat mengganti metode
toString()
untuk objek dalam array Anda. Atau, untuk membuat tampilan setiap item yang berbeda denganTextView
(misalnya, jika Anda menginginkanImageView
untuk setiap item array), perluas classArrayAdapter
dan gantigetView()
untuk menampilkan tipe tampilan yang Anda inginkan untuk setiap item. SimpleCursorAdapter
- Gunakan adaptor ini jika data Anda berasal dari
Cursor
. Saat menggunakanSimpleCursorAdapter
, Anda harus menentukan tata letak yang akan digunakan untuk tiap baris dalamCursor
dan kolom dalamCursor
yang harus dimasukkan ke dalam tampilan tata letak. Misalnya, jika Anda ingin untuk membuat daftar nama orang dan nomor ponsel, Anda bisa melakukan kueri yang mengembalikanCursor
berisi satu baris untuk setiap orang serta kolom-kolom untuk nama dan nomor. Selanjutnya, Anda membuat array string yang menetapkan kolom dariCursor
yang Anda inginkan dalam tata letak untuk setiap hasil dan array integer yang menetapkan tampilan yang sesuai untuk menempatkan 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 tata letak yang akan digunakan untuk setiap hasil,Cursor
yang berisi hasil tersebut, dan dua array 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 dalamCursor
menggunakan tata letak yang disediakan dengan memasukkan setiap itemfromColumns
ke dalam tampilantoViews
yang sesuai.
Jika, selama masa aktif aplikasi, Anda mengubah data pokok yang dibaca oleh adaptor,
Anda perlu memanggil notifyDataSetChanged()
. Tindakan ini akan
memberi tahu tampilan terkait bahwa data telah diubah dan akan otomatis dimuat ulang.
Menangani peristiwa klik
Anda dapat merespons peristiwa klik pada setiap item dalam AdapterView
dengan
mengimplementasikan antarmuka AdapterView.OnItemClickListener
. 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);
Referensi lainnya
Tata letak digunakan pada aplikasi demo Sunflower.