Tata letak dalam tampilan

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

Tata letak mendefinisikan struktur untuk antarmuka pengguna di aplikasi Anda, seperti di sebuah aktivitas Anda. Semua elemen dalam dibuat menggunakan hierarki View dan ViewGroup objek terstruktur dalam jumlah besar. View biasanya menggambar sesuatu yang dapat dilihat pengguna dan berinteraksi. ViewGroup adalah container tak terlihat yang menentukan struktur tata letak untuk View dan ViewGroup lainnya seperti yang ditunjukkan dalam gambar 1.

Gambar 1. Ilustrasi hierarki tampilan, yang mendefinisikan tata letak UI.

Objek View sering disebut widget dan dapat menjadi salah satu banyak subclass, seperti Button atau TextView. Tujuan Objek ViewGroup biasanya disebut tata letak dan dapat berupa salah satu dari banyak jenis yang menyediakan struktur tata letak yang berbeda, seperti LinearLayout atau ConstraintLayout.

Anda dapat mendeklarasikan tata letak dengan dua cara:

  • Deklarasikan elemen UI dalam XML. Android menyediakan XML yang mudah kosakata yang sesuai dengan class dan subclass View, seperti untuk widget dan tata letak. Anda juga dapat menggunakan Layout Editor untuk membuat XML menggunakan antarmuka {i>drag-and-drop<i}.

  • Buat instance elemen tata letak saat runtime. Aplikasi Anda dapat membuat objek View dan ViewGroup serta memanipulasi properti secara terprogram.

Mendeklarasikan UI dalam XML memungkinkan Anda memisahkan presentasi aplikasi dari kode yang mengontrol perilakunya. Menggunakan file XML juga membuat lebih mudah untuk menyediakan tata letak yang berbeda untuk berbagai ukuran dan orientasi layar. Ini adalah kita bahas lebih lanjut di Mendukung layar yang berbeda ukuran.

Framework Android memberi Anda fleksibilitas untuk menggunakan salah satu atau kedua metode ini untuk membangun UI aplikasi Anda. Misalnya, Anda dapat mendeklarasikan atribut tata letak default dalam XML, lalu memodifikasi tata letak saat runtime.

Menulis XML

Dengan menggunakan kosakata XML Android, Anda bisa dengan cepat mendesain tata letak UI dan elemen layar yang dikandungnya, dengan cara yang sama seperti Anda membuat laman web dalam format HTML dengan serangkaian elemen tersarang.

Setiap file tata letak harus berisi persis satu elemen root, yang harus berupa Objek View atau ViewGroup. Setelah Anda menentukan root Anda bisa menambahkan objek tata letak atau widget tambahan sebagai elemen turunan ke secara bertahap membangun hierarki View yang menentukan tata letak Anda. Sebagai berikut adalah tata letak XML yang menggunakan LinearLayout vertikal untuk tahan 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 kode Ekstensi .xml di res/layout/ project Android Anda direktori sehingga dapat terkompilasi dengan benar.

Untuk informasi selengkapnya tentang sintaksis untuk 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 dalam Activity.onCreate() implementasi callback. Lakukan dengan memanggil setContentView(), meneruskan referensi ke resource tata letak Anda dalam bentuk: R.layout.layout_file_name. Misalnya, jika XML Anda disimpan sebagai main_layout.xml, muatkan untuk Activity sebagai 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 saat Activity diluncurkan. Untuk selengkapnya informasi tentang siklus proses aktivitas, lihat Pengantar lainnya.

Atribut

Setiap objek View dan ViewGroup mendukungnya sendiri berbagai atribut XML. Beberapa atribut bersifat khusus untuk View . Misalnya, TextView mendukung textSize . Namun, atribut ini juga diwarisi oleh View yang memperluas class ini. Beberapa bersifat umum untuk semua View objek, karena diwarisi dari class View root, seperti atribut id. Atribut lain dianggap sebagai tata letak parameter, yang merupakan atribut yang mendeskripsikan orientasi tata letak tertentu dari objek View, seperti yang ditentukan oleh induk objek tersebut Objek ViewGroup.

ID

Setiap objek View dapat memiliki ID bilangan bulat yang terkait dengannya untuk secara unik mengidentifikasi View dalam hierarki. Saat aplikasi dikompilasi, ID ini dirujuk sebagai bilangan bulat, tetapi ID 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 atribut Class View. Anda akan sangat sering menggunakannya. Sintaks untuk ID di dalam Tag XML adalah sebagai berikut:

android:id="@+id/my_button"

Simbol at (@) di awal string menunjukkan bahwa parser XML mengurai dan memperluas ID string lainnya dan mengidentifikasinya sebagai resource ID. Simbol plus (+) berarti ini adalah nama resource baru yang harus dibuat dan ditambahkan ke resource Anda di 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 sebagai berikut:

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

Namespace paket android menunjukkan bahwa Anda mereferensikan ID dari class resource android.R, bukan ID lokal resource Google Cloud.

Untuk membuat tampilan dan mereferensikannya dari aplikasi, Anda dapat menggunakan sebagai berikut:

  1. Tentukan tampilan di 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"/>
    
  2. Membuat instance objek tampilan dan mengambilnya dari tata letak, biasanya dalam onCreate() seperti yang 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 mendefinisikan tata letak secara relatif terhadap yang lain yang setara, yang dirujuk oleh ID unik.

Sebuah ID tidak harus unik di seluruh pohon, tetapi harus unik di bagian pohon yang Anda telusuri. Mungkin seringkali seluruh pohon, jadi sebaiknya buat keunikan jika memungkinkan.

Parameter tata letak

Atribut tata letak XML bernama layout_something menentukan parameter tata letak untuk View yang sesuai untuk ViewGroup tempatnya tinggal.

Setiap class ViewGroup mengimplementasikan class bertingkat yang memperluas ViewGroup.LayoutParams. Subclass ini berisi jenis properti yang menentukan ukuran dan posisi masing-masing tampilan turunan, sesuai dengan kelompok tampilan tersebut. Seperti yang ditunjukkan pada gambar 2, induk grup tampilan mendefinisikan parameter tata letak untuk setiap tampilan turunan, termasuk turunan kelompok tampilan.

Gambar 2. Visualisasi hierarki tampilan dengan tata letak yang terkait dengan setiap tampilan.

Setiap subclass LayoutParams memiliki sintaksisnya sendiri untuk menetapkan masing-masing. Setiap elemen turunan harus menentukan LayoutParams yang sesuai untuk induknya, meskipun mungkin juga mendefinisikan LayoutParams untuk turunannya sendiri.

Semua grup tampilan menyertakan lebar dan tinggi, menggunakan layout_width dan layout_height, serta setiap tampilan diperlukan untuk menentukannya. Banyak LayoutParams menyertakan margin dan batas opsional.

Anda dapat menentukan lebar dan tinggi dengan ukuran yang tepat, tetapi Anda mungkin tidak ingin sering melakukan hal ini. Lebih sering, Anda menggunakan salah satu konstanta ini untuk mengatur {i>width<i} (lebar atau tinggi):

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

Secara umum, kami tidak merekomendasikan menentukan lebar dan tinggi tata letak menggunakan satuan mutlak, seperti piksel. Pendekatan yang lebih baik adalah menggunakan pengukuran relatif, seperti satuan piksel kepadatan mandiri (dp), wrap_content, atau match_parent, karena membantu aplikasi Anda ditampilkan dengan benar di seluruh berbagai ukuran layar perangkat. Jenis pengukuran yang diterima didefinisikan dalam Resource tata letak.

Posisi tata letak

Tampilan memiliki geometri persegi panjang. Model 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 mewakili tampilan. Metode kedua menampilkan koordinat atas (y) persegi panjang yang mewakili tampilan. Metode ini menampilkan lokasi tampilan relatif terhadap induknya. Misalnya, jika getLeft() menampilkan 20, ini berarti terletak 20 piksel ke kanan dari tepi kiri garis orang tua.

Selain itu, ada metode praktis untuk menghindari komputasi yang tidak perlu: yaitu getRight() dan getBottom(). Metode ini mengembalikan koordinat tepi kanan dan bawah objek persegi panjang yang mewakili tampilan. Misalnya, memanggil getRight() adalah yang 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 disebut sebagai lebar terukur dan tinggi yang diukur. Dimensi ini menentukan seberapa besar tampilan yang diinginkan dalam induknya. Anda bisa mendapatkan 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, saat menggambar dan setelah tata letak. Ini mungkin, tetapi tidak harus, berbeda dari lebar dan tinggi terukur. Anda kita bisa mendapatkan lebar dan tinggi dengan memanggil getWidth() dan getHeight().

Untuk mengukur dimensinya, tampilan akan memperhitungkan pengisinya. Padding dinyatakan dalam {i>pixel<i} untuk bagian kiri, atas, kanan, dan bawah tampilan. Anda bisa menggunakan {i>padding<i} untuk meng-offset isi tampilan dengan sejumlah {i>pixel<i}. Misalnya, padding kiri dua piksel mendorong konten tampilan sebanyak dua piksel di sebelah kanan dari tepi kiri. Anda dapat mengatur padding menggunakan setPadding(int, int, int, int) dan melakukan kueri dengan memanggil getPaddingLeft(), getPaddingTop(), getPaddingRight(), dan getPaddingBottom().

Meskipun dapat mendefinisikan padding, tampilan tidak mendukung margin. Namun, kelompok tampilan mendukung margin. Lihat ViewGroup dan ViewGroup.MarginLayoutParams untuk informasi selengkapnya.

Untuk informasi selengkapnya tentang dimensi, lihat Dimensi.

Selain mengatur margin dan padding secara terprogram, Anda juga dapat mengaturnya dalam tata letak XML Anda, 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. Tujuan TextView memiliki margin dan padding seragam yang diterapkan di sekeliling, dan Button menunjukkan cara menerapkannya secara independen ke berbagai tepi.

Tata letak umum

Setiap subclass dari class ViewGroup menyediakan cara unik untuk menampilkan tampilan yang Anda sarangkan di dalamnya. Jenis tata letak yang paling fleksibel dan yang yang menyediakan alat terbaik untuk menjaga hierarki tata letak Anda tetap dangkal, adalah ConstraintLayout.

Berikut adalah beberapa jenis tata letak umum yang disertakan dalam Android terkelola sepenuhnya.

Membuat tata letak linear

Mengatur turunannya ke dalam satu baris horizontal atau vertikal dan membuat scrollbar jika panjang jendela melebihi panjang layar.

Membuat aplikasi web di WebView

Menampilkan halaman web.

Membuat daftar dinamis

Ketika konten untuk tata letak dinamis atau tidak ditentukan sebelumnya, Anda dapat penggunaan RecyclerView atau subclass dari AdapterView. RecyclerView umumnya adalah opsi yang lebih baik, karena menggunakan memori lebih efisien daripada AdapterView.

Tata letak umum yang dapat digunakan dengan RecyclerView dan AdapterView mencakup hal berikut:

Daftar

Menampilkan daftar kolom tunggal yang bergulir.

Petak

Menampilkan petak kolom dan baris yang bergulir.

RecyclerView menawarkan lebih banyak kemungkinan dan opsi untuk buat pengelola tata letak.

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 membangun tampilan untuk AdapterView. Dua adapter yang paling umum adalah:

ArrayAdapter
Gunakan adaptor ini bila sumber data berupa array. Secara {i>default<i}, ArrayAdapter membuat tampilan untuk setiap item array dengan memanggil toString() di setiap item dan menempatkan kontennya di TextView.

Misalnya, jika Anda memiliki sebuah array {i>string<i} yang ingin ditampilkan dalam ListView, inisialisasi ArrayAdapter baru menggunakan untuk menentukan 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() pada ListView 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 untuk setiap item yang berbeda dari TextView—misalnya, jika Anda menginginkan ImageView untuk setiap item array—perluas class ArrayAdapter dan abaikan getView() untuk mengembalikan jenis tampilan yang Anda inginkan untuk setiap item.

SimpleCursorAdapter
Gunakan adaptor ini jika data Anda berasal dari Cursor. Saat menggunakan SimpleCursorAdapter, tentukan tata letak yang akan digunakan setiap baris di Cursor dan kolom mana di Cursor yang ingin Anda sisipkan ke dalam tampilan tata letak yang Anda inginkan. Misalnya, jika Anda ingin membuat daftar nama orang dan nomor telepon angka, Anda dapat menjalankan kueri yang menampilkan nilai Cursor yang berisi baris untuk setiap orang dan kolom untuk nama dan nomor. Anda kemudian buat array string yang menentukan kolom mana dari Cursor yang Anda inginkan dalam tata letak untuk setiap hasil dan bilangan bulat yang menetapkan tampilan yang sesuai, dan setiap kolom harus ditempatkan:

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 yang digunakan untuk setiap hasil, Cursor yang berisi atribut hasil, dan kedua himpunan tersebut:

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);
    

Kemudian, SimpleCursorAdapter membuat tampilan untuk setiap baris di Cursor menggunakan tata letak yang disediakan dengan memasukkan masing-masing fromColumns item ke toViews yang sesuai {i>view<i}.

Jika selama masa aktif aplikasi, Anda mengubah data pokok yang dibaca oleh adaptor Anda, panggil notifyDataSetChanged(). Cara ini akan memberi tahu tampilan terlampir bahwa data telah diubah dan dimuat ulang itu sendiri.

Menangani peristiwa klik

Anda dapat merespons peristiwa klik pada setiap item di AdapterView dengan menerapkan AdapterView.OnItemClickListener dalam antarmuka berbasis web yang sederhana. 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

Lihat bagaimana tata letak digunakan dalam Bunga Matahari aplikasi demo di GitHub.