Layout

Layout mendefinisikan struktur visual untuk antarmuka pengguna, seperti UI sebuah aktivitas atau widget aplikasi. Anda dapat mendeklarasikan layout dengan dua cara:

  • Deklarasikan elemen UI dalam XML. Android menyediakan sebuah kosakata XML sederhana yang sesuai dengan kelas dan subkelas View, seperti halnya untuk widget dan layout.
  • Buat instance elemen layout saat waktu proses. Aplikasi Anda bisa membuat objek View dan ViewGroup (dan memanipulasi propertinya) lewat program.

Kerangka kerja Android memberi Anda fleksibilitas untuk menggunakan salah satu atau kedua metode ini guna mendeklarasikan dan mengelola UI aplikasi Anda. Misalnya, Anda bisa mendeklarasikan layout default aplikasi Anda dalam XML, termasuk elemen-elemen layar yang akan muncul di dalamnya dan di propertinya. Anda nanti bisa menambahkan kode dalam aplikasi yang akan memodifikasi status objek layar, termasuk yang dideklarasikan dalam XML, saat waktu proses.

Keuntungan mendeklarasikan UI dalam XML adalah karena hal ini memungkinkan Anda memisahkan penampilan aplikasi dari kode yang mengontrol perilakunya dengan lebih baik. Keterangan UI Anda bersifat eksternal bagi kode aplikasi Anda, yang berarti bahwa Anda bisa memodifikasi atau menyesuaikannya tanpa harus memodifikasi dan mengompilasi ulang kode sumber. Misalnya, Anda bisa membuat layout XML untuk berbagai orientasi layar, berbagai ukuran layar perangkat, dan berbagai bahasa. Selain itu, mendeklarasikan layout dalam XML akan mempermudah Anda memvisualisasikan struktur UI, sehingga lebih mudah men-debug masalahnya. Karena itu, dokumen ini berfokus pada upaya mengajari Anda cara mendeklarasikan layout dalam XML. Jika Anda tertarik dalam membuat instance objek View saat waktu proses, lihat referensi kelas ViewGroup dan View.

Secara umum, kosakata XML untuk mendeklarasikan elemen UI mengikuti dengan sangat mirip struktur serta penamaan kelas dan metode, dengan nama elemen dipadankan dengan nama kelas dan nama atribut dipadankan dengan metode. Sebenarnya, pemadanan ini kerap kali begitu jelas sehingga Anda bisa menebak atribut XML yang berpadanan dengan sebuah metode kelas, atau menebak kelas yang berpadanan dengan sebuah elemen XML. Akan tetapi, perhatikan bahwa tidak semua kosakata identik. Dalam beberapa kasus, ada sedikit perbedaan penamaan. Misalnya , elemen EditText memiliki atribut text yang berpadanan dengan EditText.setText().

Tip: Ketahui selengkapnya berbagai tipe layout dalam Objek Layout Umum.

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, simpanlah file dengan ekstensi .xml, dalam direktori res/layout/ proyek 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 sebuah sumber daya View. Anda harus memuat sumber daya layout dari kode aplikasi, dalam implementasi callback Activity.onCreate(). Lakukan dengan memanggil setContentView(), dengan meneruskan acuan ke sumber daya layout berupa: R.layout.layout_file_name. Misalnya, jika XML layout Anda disimpan sebagai main_layout.xml, Anda akan memuatnya untuk Activity seperti ini:

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

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

Atribut

Setiap objek View dan ViewGroup mendukung variasi atribut XML-nya sendiri. Sebagian atribut bersifat spesifik untuk objek View (misalnya, TextView mendukung atribut textSize ), namun atribut ini juga diwarisi oleh sembarang objek View yang dapat memperluas kelas ini. Sebagian atribut bersifat umum untuk semua objek View, karena diwarisi dari kelas View akar (seperti atribut id). Dan, atribut lain dianggap sebagai "parameter layout" yaitu atribut yang menjelaskan orientasi layout tertentu dari objek View, seperti yang didefinisikan oleh objek ViewGroup induk dari objek itu.

ID

Objek View apa saja dapat memiliki ID integer yang dikaitkan dengannya, untuk mengidentifikasi secara unik View dalam pohon. Bila aplikasi dikompilasi, ID ini akan diacu sebagai integer, namun ID biasanya ditetapkan dalam file XML layout sebagai string, dalam atribut id. Ini atribut XML yang umum untuk semua objek View (yang didefinisikan oleh kelas View) dan Anda akan sering sekali menggunakannya. Sintaks untuk ID 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 kerangka kerja Android. Saat mengacu sebuah ID sumber daya Android, Anda tidak memerlukan simbol tanda tambah, namun harus menambahkan namespace paket android, sehingga:

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

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

Untuk membuat tampilan dan mengacunya 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 itu dari layout (biasanya dalam metode onCreate()):
    Button myButton = (Button) findViewById(R.id.my_button);
    

Mendefinisikan ID untuk objek tampilan adalah penting saat membuat RelativeLayout. Dalam layout relatif, tampilan saudara bisa mendefinisikan layout secara relatif terhadap tampilan saudara lainnya, yang diacu 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 bila memungkinkan).

Parameter Layout

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

Setiap kelas ViewGroup mengimplementasikan kelas tersarang 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 1, grup tampilan induk mendefinisikan parameter layout untuk masing-masing tampilan anak (termasuk grup tampilan anak).

Gambar 1. 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 bagi 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. Lebih sering, 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 materinya.
  • 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 tidaklah 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 benar pada berbagai ukuran layar perangkat. Tipe ukuran yang diterima didefinisikan dalam dokumen Sumber Daya yang Tersedia.

Posisi Layout

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

Lokasi tampilan dapat diambil dengan memanggil metode getLeft() dan getTop(). Metode terdahulu mengembalikan koordinat kiri, atau X, persegi panjang yang mewakili tampilan. Metode selanjutnya mengembalikan koordinat atas, atau Y, persegi panjang yang mewakili tampilan. Kedua metode ini mengembalikan lokasi tampilan relatif terhadap induknya. Misalnya, bila getLeft() mengembalikan 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 mengembalikan 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 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 metode setPadding(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 sarangkan di dalamnya. Di bawah ini adalah beberapa tipe layout lebih umum yang dibuat ke dalam platform Android.

Catatan: Walaupun Anda bisa menyarangkan 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 tersarang 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

Bila isi layout bersifat dinamis atau tidak dipastikan sebelumnya, Anda bisa menggunakan layout yang menjadi subkelas AdapterView untuk mengisi layout dengan tampilan saat waktu proses. Subkelas dari kelas AdapterView menggunakan Adapter untuk mengikat data ke layoutnya. Adapter berfungsi sebagai penghubung antara sumber data dan layoutAdapterViewAdapter menarik 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 mengikat 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 menarik berbagai jenis data dan membangun tampilan untuk AdapterView. Dua adaptor 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:

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 tinggal panggil setAdapter() pada ListView Anda:

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 mengembalikan tipe tampilan yang Anda inginkan bagi setiap item.

SimpleCursorAdapter
Gunakan adaptor ini bila 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 untuk membuat daftar nama orang dan nomor ponsel, Anda bisa melakukan kueri yang mengembalikan Cursor berisi satu baris untuk setiap orang serta kolom-kolom untuk nama dan nomor. 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:

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

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

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, Anda mengubah data yang mendasarinya, yang dibaca oleh adaptor, 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 kejadian klik pada setiap item dalam AdapterView dengan menerapkan antarmuka AdapterView.OnItemClickListener. Misalnya:

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

listView.setOnItemClickListener(mMessageClickedHandler);