Tata letak dalam tampilan
Tata letak menentukan struktur untuk antarmuka pengguna di aplikasi Anda, seperti
dalam
aktivitas. Semua elemen dalam
tata letak dibuat menggunakan hierarki
objek
View
dan
ViewGroup
. View
biasanya menggambar sesuatu yang dapat dilihat dan
berinteraksi dengan pengguna. ViewGroup
adalah penampung tidak terlihat yang menentukan
struktur tata letak untuk View
dan objek ViewGroup
lainnya, seperti yang ditunjukkan pada gambar 1.
Objek View
sering disebut widget dan dapat menjadi salah satu dari
banyak subclass, seperti
Button
atau
TextView
. Objek
ViewGroup
biasanya disebut tata letak dan dapat berupa salah satu
dari banyak jenis yang memberikan struktur tata letak berbeda, 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
View
, seperti untuk widget dan tata letak. Anda juga dapat menggunakan Layout Editor Android Studio untuk membuat tata letak XML menggunakan antarmuka tarik lalu lepas. - Buat instance elemen tata letak saat runtime. Aplikasi Anda dapat membuat
objek
View
danViewGroup
serta memanipulasi propertinya secara terprogram.
Dengan mendeklarasikan UI dalam XML, Anda dapat memisahkan presentasi aplikasi dari kode yang mengontrol perilakunya. Penggunaan file XML juga akan mempermudah penyediaan tata letak yang berbeda untuk berbagai ukuran dan orientasi layar. Hal ini dibahas lebih lanjut 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, lalu mengubah tata letak tersebut saat runtime.
Menulis XML
Dengan menggunakan kosakata XML Android, Anda dapat dengan cepat mendesain tata letak UI dan elemen layar yang ada di dalamnya, sama seperti saat membuat halaman web dalam HTML dengan serangkaian elemen bertingkat.
Setiap file tata letak harus berisi persis satu elemen root, yang harus berupa objek
View
atau ViewGroup
. Setelah menentukan elemen
root, Anda dapat menambahkan objek tata letak atau widget tambahan sebagai elemen turunan untuk
mem-build hierarki View
yang menentukan tata letak secara bertahap. Misalnya, 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 mendeklarasikan tata letak dalam XML, simpan file dengan
ekstensi .xml
di direktori res/layout/
project Android
Anda agar dapat dikompilasi dengan benar.
Untuk mengetahui informasi selengkapnya tentang sintaksis file XML tata letak, lihat Resource tata letak.
Memuat resource XML
Saat mengompilasi aplikasi, masing-masing file tata letak XML akan dikompilasikan menjadi
resource View
. Muat resource tata letak di implementasi callback
Activity.onCreate()
aplikasi Anda. Lakukan dengan memanggil
setContentView()
,
dengan meneruskan referensi ke resource tata letak dalam bentuk:
R.layout.layout_file_name
. Misalnya, jika tata letak XML
Anda disimpan sebagai main_layout.xml
, muat tata letak tersebut untuk
Activity
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); }
Framework Android memanggil metode callback onCreate()
di
Activity
Anda saat Activity
diluncurkan. Untuk informasi
selengkapnya tentang siklus proses aktivitas, lihat
Pengantar
aktivitas.
Atribut
Setiap objek View
dan ViewGroup
mendukung berbagai
atribut XML-nya sendiri. Beberapa atribut bersifat khusus untuk objek
View
. Misalnya, TextView
mendukung atribut
textSize
. Namun, atribut ini juga diwarisi oleh objek View
yang memperluas class ini. Sebagian bersifat umum untuk semua objek View
, karena diwarisi dari class View
root, seperti
atribut id
. Atribut lain dianggap sebagai parameter
tata letak, yaitu atribut yang mendeskripsikan orientasi tata letak tertentu
dari objek View
, seperti yang ditentukan oleh objek ViewGroup
induk objek tersebut.
ID
Setiap objek View
dapat memiliki ID bilangan bulat yang terkait dengannya untuk mengidentifikasi View
secara unik dalam hierarki. Saat aplikasi
dikompilasi, ID ini direferensikan sebagai bilangan bulat, tetapi ID tersebut biasanya ditetapkan
dalam file XML tata letak sebagai string dalam atribut id
. Ini adalah
atribut XML yang umum untuk semua objek View
, dan ditentukan oleh
class View
. Anda sering menggunakannya. Sintaksis untuk ID di dalam
tag XML adalah sebagai berikut:
android:id="@+id/my_button"
Simbol at (@) di awal string menunjukkan bahwa
Parser XML akan mengurai dan meluaskan sisa string ID dan mengidentifikasinya sebagai
resource ID. Simbol plus (+) berarti ini adalah nama resource baru
yang harus dibuat dan ditambahkan ke resource Anda dalam file
R.java
.
Framework Android menawarkan banyak resource ID lainnya. Saat mereferensikan
ID resource Android, Anda tidak memerlukan simbol plus, tetapi harus menambahkan
namespace paket android
seperti berikut:
android:id="@android:id/empty"
Namespace paket android
menunjukkan bahwa Anda mereferensikan
ID dari class resource android.R
, bukan class
resource lokal.
Untuk membuat tampilan dan mereferensikannya dari aplikasi, Anda dapat menggunakan pola umum sebagai berikut:
- Tentukan tampilan dalam file tata letak dan tetapkan ID unik, seperti dalam
contoh berikut:
<Button android:id="@+id/my_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/my_button_text"/>
- Buat instance objek tampilan dan ambil dari tata letak,
biasanya dalam metode
onCreate()
, seperti ditunjukkan dalam contoh berikut: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 penting saat membuat
RelativeLayout
.
Dalam tata letak relatif, tampilan yang setara dapat menentukan tata letak secara relatif terhadap
tampilan seinduk lainnya, yang dirujuk oleh ID unik.
ID tidak harus unik di seluruh hierarki, tetapi harus unik di dalam bagian hierarki yang Anda telusuri. Sering kali bisa berupa seluruh pohon, jadi sebaiknya buat unik jika memungkinkan.
Parameter tata letak
Atribut tata letak XML bernama layout_something
menentukan
parameter tata letak untuk View
yang sesuai untuk
ViewGroup
tempatnya berada.
Setiap class ViewGroup
menerapkan class bertingkat yang memperluas
ViewGroup.LayoutParams
.
Subclass ini berisi jenis properti yang mendefinisikan ukuran dan posisi setiap
tampilan turunan, sebagaimana mestinya untuk grup tampilan. Seperti yang ditunjukkan dalam gambar 2, kelompok tampilan
induk menentukan parameter tata letak untuk setiap tampilan turunan, termasuk kelompok
tampilan turunan.
Setiap subclass LayoutParams
memiliki sintaksisnya sendiri untuk menetapkan
nilai. Setiap elemen turunan harus menetapkan LayoutParams
yang
sesuai untuk induknya, meskipun elemen tersebut juga dapat menentukan
LayoutParams
yang berbeda untuk turunannya sendiri.
Semua grup tampilan berisi lebar dan tinggi, dengan menggunakan layout_width
dan layout_height
, dan setiap tampilan diperlukan untuk mendefinisikannya. Banyak
LayoutParams
yang menyertakan margin dan batas opsional.
Anda dapat menentukan lebar dan tinggi dengan ukuran yang tepat, tetapi Anda mungkin tidak ingin sering melakukannya. Sering kali, Anda akan menggunakan salah satu konstanta ini untuk menyetel lebar atau tinggi:
wrap_content
: memberi tahu tampilan Anda agar menyesuaikan ukurannya sendiri dengan dimensi yang dibutuhkan oleh kontennya.match_parent
: memberi tahu tampilan Anda agar menjadi sebesar yang diizinkan oleh kelompok tampilan induknya.
Secara umum, kami tidak merekomendasikan penetapan lebar dan tinggi tata letak menggunakan
satuan absolut seperti piksel. Pendekatan yang lebih baik adalah menggunakan ukuran relatif,
seperti satuan piksel kepadatan mandiri (dp), wrap_content
, atau
match_parent
, karena membantu aplikasi Anda ditampilkan dengan benar di
berbagai ukuran layar perangkat. Jenis pengukuran yang diterima ditentukan di
Resource tata letak.
Posisi tata letak
Sebuah tampilan memiliki geometri persegi panjang. Bidang ini memiliki lokasi, yang dinyatakan sebagai pasangan koordinat kiri dan atas, serta dua dimensi, yang dinyatakan sebagai lebar dan tinggi. Satuan untuk lokasi dan dimensi adalah piksel.
Anda dapat mengambil lokasi tampilan dengan memanggil metode
getLeft()
dan
getTop()
.
Metode pertama menampilkan koordinat kiri (x) persegi panjang yang merepresentasikan
tampilan. Kode kedua menampilkan koordinat (y) atas persegi panjang
yang mewakili tampilan. Metode ini menampilkan lokasi tampilan relatif terhadap
induknya. Misalnya, jika getLeft()
menampilkan 20, berarti
tampilan terletak 20 piksel di sebelah kanan tepi kiri induk
langsungnya.
Selain itu, ada metode praktis untuk menghindari komputasi yang tidak perlu:
yaitu
getRight()
dan
getBottom()
.
Metode ini menampilkan koordinat tepi kanan dan bawah
persegi panjang yang merepresentasikan tampilan. Misalnya, memanggil getRight()
mirip dengan komputasi berikut: getLeft() + getWidth()
.
Ukuran, padding, dan margin
Ukuran tampilan dinyatakan dengan lebar dan tinggi. Tampilan memiliki dua pasang nilai lebar dan tinggi.
Pasangan pertama dikenal sebagai lebar terukur dan
tinggi terukur. Dimensi ini menentukan seberapa besar tampilan
yang diinginkan dalam induknya. Anda dapat memperoleh dimensi terukur dengan memanggil
getMeasuredWidth()
dan
getMeasuredHeight()
.
Pasangan kedua disebut sebagai lebar dan tinggi, atau terkadang
lebar gambar dan tinggi gambar. Dimensi ini menentukan
ukuran tampilan sebenarnya di layar, pada waktu menggambar dan setelah tata letak. Nilai
ini mungkin, tetapi tidak harus, berbeda dengan lebar dan tinggi terukur. Anda
bisa memperoleh lebar dan tinggi dengan memanggil
getWidth()
dan
getHeight()
.
Untuk mengukur dimensinya, tampilan akan memperhitungkan pengisinya. Padding
dinyatakan dalam piksel untuk bagian kiri, atas, kanan, dan bawah tampilan.
Anda dapat menggunakan padding untuk mengimbangi konten tampilan dengan jumlah piksel
tertentu. Misalnya, padding kiri sebanyak dua mendorong konten tampilan dua piksel
ke kanan dari tepi kiri. Anda dapat menyetel padding menggunakan metode
setPadding(int, int, int, int)
dan membuat kuerinya dengan memanggil
getPaddingLeft()
,
getPaddingTop()
,
getPaddingRight()
,
dan
getPaddingBottom()
.
Meskipun dapat mendefinisikan padding, tampilan tidak mendukung margin. Namun,
grup tampilan mendukung margin. Lihat
ViewGroup
dan
ViewGroup.MarginLayoutParams
untuk mengetahui informasi selengkapnya.
Untuk mengetahui informasi selengkapnya tentang dimensi, lihat Dimensi.
Selain menyetel margin dan padding secara terprogram, Anda juga dapat menetapkannya dalam tata letak XML, seperti yang ditunjukkan dalam contoh berikut:
<?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:layout_margin="16dp" android:padding="8dp" android:text="Hello, I am a TextView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:paddingBottom="4dp" android:paddingEnd="8dp" android:paddingStart="8dp" android:paddingTop="4dp" android:text="Hello, I am a Button" /> </LinearLayout>
Contoh sebelumnya menunjukkan margin dan padding yang diterapkan. TextView
memiliki margin dan padding seragam yang diterapkan di sekelilingnya, dan
Button
menunjukkan cara menerapkannya secara terpisah ke tepi
yang berbeda.
Tata letak umum
Setiap subclass dari class ViewGroup
menyediakan cara unik untuk
menampilkan tampilan yang Anda tempatkan di dalamnya. Jenis tata letak yang paling fleksibel, dan satu-satunya
yang menyediakan alat terbaik untuk menjaga hierarki tata letak Anda tetap dangkal, adalah
ConstraintLayout
.
Berikut ini adalah beberapa jenis tata letak umum yang dibangun ke dalam platform Android.
Mengatur turunannya ke dalam satu baris horizontal atau vertikal dan membuat scrollbar jika panjang jendela melebihi panjang layar.
Membuat daftar dinamis
Jika konten untuk tata letak bersifat dinamis atau tidak ditentukan sebelumnya, Anda dapat
menggunakan
RecyclerView
atau
subclass
dari AdapterView
.
RecyclerView
umumnya adalah opsi yang lebih baik karena menggunakan memori
secara lebih efisien daripada AdapterView
.
Tata letak umum yang dapat dilakukan dengan RecyclerView
dan
AdapterView
mencakup hal berikut:
RecyclerView
menawarkan lebih banyak kemungkinan dan
opsi untuk
membuat pengelola
tata letak kustom.
Mengisi tampilan adaptor dengan data
Anda dapat mengisi
AdapterView
seperti ListView
atau
GridView
dengan
mengikat instance AdapterView
ke
Adapter
,
yang 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 adapter yang paling umum adalah:
ArrayAdapter
- Gunakan adaptor ini bila sumber data berupa array. Secara default,
ArrayAdapter
akan membuat tampilan untuk setiap item array dengan memanggiltoString()
pada setiap item dan menempatkan konten dalamTextView
.Misalnya, jika Anda memiliki array string yang ingin ditampilkan dalam
ListView
, lakukan inisialisasiArrayAdapter
baru menggunakan 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 untuk konstruktor ini adalah sebagai berikut:
- Aplikasi Anda
Context
- Tata letak yang berisi
TextView
untuk setiap string dalam array - Array string
Lalu, panggil
setAdapter()
diListView
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 tampilan setiap item, Anda dapat mengganti metode
toString()
untuk objek dalam array Anda. Atau, untuk membuat tampilan bagi setiap item yang bukanTextView
—misalnya, jika Anda menginginkanImageView
untuk setiap item array—perluas classArrayAdapter
dan gantigetView()
untuk menampilkan jenis tampilan yang Anda inginkan untuk setiap item. - Aplikasi Anda
SimpleCursorAdapter
- Gunakan adaptor ini jika data Anda berasal dari
Cursor
. Saat menggunakanSimpleCursorAdapter
, tentukan tata letak yang akan digunakan untuk setiap baris dalamCursor
dan kolom mana diCursor
yang ingin disisipkan ke dalam tampilan tata letak yang Anda inginkan. Misalnya, jika ingin membuat daftar nama orang dan nomor telepon, Anda dapat melakukan kueri yang menampilkanCursor
yang berisi satu baris untuk setiap orang serta kolom untuk nama dan nomor. Selanjutnya, buat array string yang menentukan kolom dariCursor
yang Anda inginkan dalam tata letak untuk setiap hasil dan array bilangan bulat yang menentukan tampilan terkait yang harus ditempatkan oleh setiap 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};
Saat Anda membuat instance
SimpleCursorAdapter
, teruskan tata letak yang akan digunakan untuk setiap hasil,Cursor
yang berisi hasil tersebut, dan kedua 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 pakai aplikasi Anda mengubah data pokok yang
dibaca oleh adaptor, panggil
notifyDataSetChanged()
.
Hal ini akan memberi tahu tampilan terlampir bahwa data telah diubah dan akan dimuat ulang
dengan sendirinya.
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 tambahan
Lihat cara tata letak digunakan dalam aplikasi demo Sunflower di GitHub.