Sebelum Jetpack Compose muncul pada 2021, semua UI Android ditulis dengan XML. Hingga kini, banyak codebase masih memakai XML dan library pihak ketiga tetap mendukungnya. Memahami LinearLayout, ConstraintLayout, dan komponen umum seperti TextView, Button, dan RecyclerView tetap relevan baik untuk membaca kode lama maupun bekerja sama dengan tim yang belum migrasi ke Compose. Bab ini memetakan konsep kunci layout XML dan menunjukkan bagaimana setiap layout manager menyusun children-nya.

LinearLayout dan ConstraintLayout #

LinearLayout menyusun children dalam satu arah: horizontal atau vertical. Setiap child diberi posisi berurutan sesuai urutan deklarasi dan atribut layout_weight jika perlu. Layout ini sederhana namun tidak efisien bila hirarki bersarang dalam — setiap level LinearLayout menambah pass pengukuran.

ConstraintLayout adalah penerus yang direkomendasikan untuk layout kompleks. Layout ini bebas menempatkan view dengan constraint (garis penghubung) antar view, mirip Auto Layout di iOS atau ConstraintSolver. Keunggulan utamanya: hirarki tetap rata sehingga pass pengukuran lebih cepat.

xml res/layout/activity_main.xml (ringkas)
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/judul"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Daftar Tugas"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/tambah"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Tambah"
        app:layout_constraintTop_toBottomOf="@id/judul"
        app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Common Views #

Komponen yang paling sering dijumpai di hampir setiap aplikasi Android:

KomponenFungsi
TextViewMenampilkan teks statis
EditTextInput teks dari pengguna
ButtonTombol untuk memicu aksi
ImageViewMenampilkan gambar
RecyclerViewDaftar panjang dengan recyclable ViewHolder
ScrollViewWadah yang dapat di-scroll vertikal

RecyclerView adalah komponen paling kompleks di antara yang lain. Komponen ini tidak menampilkan data secara langsung, melainkan mendelegasikan ke Adapter yang membuat ViewHolder untuk setiap tipe baris. ViewHolder yang sudah terlihat di-recycle saat pengguna menggulir, sehingga daftar 10.000 item tetap mulus karena hanya sedikit ViewHolder yang aktif di memori.

Simulasi Layout Manager sebagai Data #

Cuplikan berikut memodelkan LinearLayout, ConstraintLayout, dan RecyclerView sebagai sealed class Layout. Method measure mengembalikan posisi setiap child seperti yang dilakukan layout manager sungguhan:

kotlin
// layouts_ui_components.kt
// Mensimulasikan tiga layout klasik Android (LinearLayout, ConstraintLayout,
// RecyclerView) sebagai model data ringkas. Menghitung posisi dan urutan
// children meniru cara layout manager menyusun view.

sealed class Layout {
    abstract fun measure(children: List<String>): List<Pair<String, Int>>
}

class LinearLayout(val orientation: String) : Layout() {
    override fun measure(children: List<String>): List<Pair<String, Int>> {
        val pos = if (orientation == "horizontal") 0 else 0
        return children.mapIndexed { i, name -> name to (pos + i * 50) }
    }
}

class ConstraintLayout : Layout() {
    override fun measure(children: List<String>): List<Pair<String, Int>> {
        // ConstraintLayout bebas menempatkan view di koordinat (x,y) 2D
        return children.mapIndexed { i, name -> name to (i * 80) }
    }
}

class RecyclerView(val adapter: ListAdapter) : Layout() {
    override fun measure(children: List<String>): List<Pair<String, Int>> =
        adapter.bind().mapIndexed { i, name -> name to (i * 72) }
}

class ListAdapter(private val data: List<String>) {
    fun bind(): List<String> = data.map { "ViewHolder($it)" }
}

fun main() {
    val items = listOf("Budi", "Siti", "Andi", "Dewi")

    val vertical = LinearLayout("vertical")
    println("LinearLayout vertical:")
    vertical.measure(items).forEach { (name, pos) -> println("  $name y=$pos") }

    val horizontal = LinearLayout("horizontal")
    println("LinearLayout horizontal:")
    horizontal.measure(items).forEach { (name, pos) -> println("  $name x=$pos") }

    val constraint = ConstraintLayout()
    println("ConstraintLayout:")
    constraint.measure(items).forEach { (name, pos) -> println("  $name pos=$pos") }

    val rv = RecyclerView(ListAdapter(items))
    println("RecyclerView (rebind adapter):")
    rv.measure(items).forEach { (vh, pos) -> println("  $vh y=$pos") }
}

Output yang Dihasilkan:

text
LinearLayout vertical:
  Budi y=0
  Siti y=50
  Andi y=100
  Dewi y=150
LinearLayout horizontal:
  Budi x=0
  Siti x=50
  Andi x=100
  Dewi x=150
ConstraintLayout:
  Budi pos=0
  Siti pos=80
  Andi pos=160
  Dewi pos=240
RecyclerView (rebind adapter):
  ViewHolder(Budi) y=0
  ViewHolder(Siti) y=72
  ViewHolder(Andi) y=144
  ViewHolder(Dewi) y=216

Perhatikan bahwa LinearLayout vertikal menempatkan children pada koordinat y berbeda, ConstraintLayout menempatkannya bebas, dan RecyclerView memanggil adapter.bind() untuk membuat ViewHolder per item. Pola pemisahan layout manager dari data inilah yang membuat RecyclerView fleksibel — kita bisa mengganti LayoutManager tanpa menyentuh adapter.

Material Design #

Material Design adalah sistem desain resmi Google yang menyediakan komponen siap pakai: MaterialButton, TextInputLayout, BottomNavigationView, FloatingActionButton, dan Snackbar. Library com.google.android.material:material harus ditambahkan di build.gradle.kts. Komponen Material mengikuti pedoman elevasi, gerak, dan tipografi yang konsisten lintas platform Google, sehingga aplikasi terasa native tanpa perlu desainer khusus.

Referensi Lanjutan #

  • Jetpack Compose — rujukan Jetpack Compose sebagai toolkit UI deklaratif modern pengganti layout berbasis XML

Selanjutnya #

Layout XML memberi pondasi pemahaman, tetapi masa depan UI Android adalah deklaratif. Chapter Jetpack Compose Fundamentals akan memperkenalkan @Composable, Column, Row, Box, dan konsep recomposition.