Data Binding — dasar, pengikatan dua arah di Android

Penulis: IT Sectr Diterbitkan: 2026-02-20 Waktu membaca: 8 mnt

Data Binding — pustaka Android Jetpack yang menghubungkan komponen UI dari tata letak XML dengan sumber data dalam kode aplikasi melalui sintaks deklaratif. Menjelaskan dasar: Data Binding menghilangkan kode boilerplate findViewById() dan memungkinkan UI diperbarui secara otomatis saat data berubah. Menurut data Google (Android Developers, 2025), Data Binding digunakan dalam 45% proyek Android, dan dalam kombinasi dengan LiveData atau StateFlow memberikan pengikatan reaktif penuh tanpa pengelolaan langganan manual.

Poin Utama

  • Data Binding — pustaka Jetpack untuk pengikatan deklaratif tata letak XML dengan sumber data melalui tag layout.
  • Pengikatan dua arah — sinkronisasi data otomatis antara View dan ViewModel melalui @={} di XML.
  • @BindingAdapter — setter kustom untuk atribut View, memungkinkan perluasan Data Binding standar.
  • Data Binding + LiveData — reaktivitas tanpa Observer: perubahan LiveData secara otomatis memperbarui UI.
  • Data Binding menghasilkan kelas Binding (misalnya ActivityMainBinding) pada tahap kompilasi, memberikan akses type-safe ke View.

Apa itu Data Binding di Android?

Data Binding — pustaka dukungan (Android Jetpack), muncul pada tahun 2015 di Google I/O dan distabilkan di Android Gradle Plugin 1.5. Ini memungkinkan pengikatan komponen UI di XML dengan sumber data (POJO, ViewModel, LiveData) langsung di tata letak, tanpa memanggil findViewById() di kode Activity atau Fragment.

Prinsip kerja: tata letak XML dibungkus dalam tag <layout>, di mana variabel <variable> dengan tipe data dideklarasikan. Di dalam tata letak, data disubstitusi melalui ekspresi dalam kurung kurawal @{}. Pada tahap kompilasi, Android Gradle Plugin menghasilkan kelas Binding (misalnya ActivityMainBinding) yang berisi referensi langsung ke View dengan tipe yang benar dan metode untuk mengatur data.

Menurut survei Android Developers (2024), Data Binding mengurangi jumlah kode UI di Activity/Fragment sebesar 30–50% dengan memindahkan logika pengikatan ke XML. Jumlah kesalahan yang terkait dengan tipe View yang salah (ClassCastException saat findViewById()) turun menjadi nol, karena semua tipe diperiksa pada tahap kompilasi.

Data Binding vs ViewBinding: mana yang harus dipilih

ViewBinding — alternatif yang lebih ringan dari Data Binding, muncul di Android Studio 3.6 (2020). ViewBinding menghasilkan kelas Binding untuk setiap file layout, tetapi tanpa dukungan untuk ekspresi, variabel, dan reaktivitas. Perbandingan berdasarkan kriteria utama:

KriteriaData BindingViewBinding
Menghasilkan kelas BindingYaYa
Ekspresi di XML (@{})YaTidak
Pengikatan dua arahYaTidak
Reaktif (LiveData)YaTidak
@BindingAdapterYaTidak
Kecepatan kompilasiLebih lambat (pemrosesan ekspresi)Lebih cepat
KompleksitasTinggiRendah

Rekomendasi Google (Android Developers, 2025): untuk sebagian besar proyek, ViewBinding sudah cukup — memberikan akses type-safe ke View tanpa overhead Data Binding. Pilih Data Binding jika membutuhkan: (1) pengikatan reaktif dengan LiveData/StateFlow dari XML, (2) pengikatan dua arah untuk formulir, (3) BindingAdapter untuk atribut kustom, (4) ekspresi di XML untuk pemformatan. Di IT Sectr, kami menggunakan ViewBinding untuk layar sederhana dan Data Binding untuk formulir kompleks dan dasbor.

Pengikatan dua arah: @{} dan @={}

Pengikatan satu arah (@{}) mentransfer data dari sumber (ViewModel) ke View. Pengikatan dua arah (@={}) menyinkronkan data di kedua arah: perubahan di View (input teks, mengalihkan Switch) secara otomatis memperbarui sumber.

xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="viewModel"
            type="com.example.app.LoginViewModel" />
    </data>

    <LinearLayout ...>
        <!-- Satu arah: data dari ViewModel ke TextView -->
        <TextView
            android:text="@{viewModel.userName}" />

        <!-- Dua arah: perubahan EditText → ViewModel, ViewModel → EditText -->
        <EditText
            android:text="@{=viewModel.email}" />

        <CheckBox
            android:checked="@{=viewModel.agreeToTerms}" />
    </LinearLayout>
</layout>

Untuk pengikatan dua arah, ViewModel harus menggunakan ObservableField, LiveData atau StateFlow. Saat data berubah melalui input pengguna, Data Binding secara otomatis memanggil setter sumber. Penting: pengikatan dua arah bekerja dengan atribut yang memiliki @InverseBindingAdapter yang ditentukan. Android menyediakan adapter bawaan untuk: text, checked, visibility, progress, rating dan atribut standar lainnya.

@BindingAdapter: atribut kustom dan konverter

@BindingAdapter — anotasi untuk fungsi ekstensi Kotlin, yang memungkinkan menentukan logika pengikatan kustom untuk atribut View apa pun. Misalnya, memuat gambar melalui Glide saat menentukan URL di XML, atau memformat tanggal saat pengikatan dengan TextView.

kotlin
// BindingAdapter untuk memuat gambar dari URL
@BindingAdapter("imageUrl")
fun ImageView.setImageUrl(url: String?) {
    Glide.with(this.context)
        .load(url)
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.error)
        .into(this)
}

// BindingAdapter dengan beberapa atribut
@BindingAdapter("visibleGone")
fun View.setVisibleGone(visible: Boolean) {
    visibility = if (visible) View.VISIBLE else View.GONE
}

// BindingAdapter dengan konverter (formatDate)
@BindingAdapter("formattedDate")
fun TextView.setFormattedDate(timestamp: Long) {
    text = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault()).format(Date(timestamp))
}
xml
<!-- Menggunakan BindingAdapter di XML -->
<ImageView
    imageUrl="@{user.avatarUrl}"
    android:layout_width="48dp"
    android:layout_height="48dp" />

<TextView
    formattedDate="@{message.createdAt}"
    visibleGone="@{message.isVisible}" />

@BindingAdapter dapat menerima beberapa atribut (requireAll = true/false), memungkinkan penggabungan nilai. Misalnya, @BindingAdapter("imageUrl", "circleCrop") — jika circleCrop true, Glide menerapkan transformasi CircleCrop. Menurut Google (Android Performance, 2024), BindingAdapter dengan Glide di Data Binding memproses hingga 60 frame per detik saat menggulir RecyclerView, karena pemuatan asinkron tidak memblokir thread UI.

Data Binding dengan LiveData dan StateFlow

Data Binding mendukung LiveData secara native sejak versi Android Architecture Components 1.0. Jika variabel di layout memiliki tipe LiveData, Binding secara otomatis berlangganan padanya dan memperbarui UI saat nilai berubah. Untuk kerja yang benar, LifecycleOwner harus diatur di kelas Binding: binding.lifecycleOwner = viewLifecycleOwner.

kotlin
// ViewModel dengan LiveData
class WeatherViewModel : ViewModel() {
    private val _temperature = MutableLiveData("--")
    val temperature: LiveData<String> get() = _temperature

    val cityName = MutableLiveData("Moskow")
    val weatherIcon = MutableLiveData(R.drawable.ic_sunny)

    fun refresh() {
        viewModelScope.launch {
            _temperature.value = weatherRepository.getTemperature()
        }
    }
}

// Di Fragment:
val binding = FragmentWeatherBinding.inflate(inflater, container, false)
binding.viewModel = weatherViewModel
binding.lifecycleOwner = viewLifecycleOwner  // ← wajib untuk LiveData
xml
<layout>
    <data>
        <variable name="viewModel" type="com.example.app.WeatherViewModel" />
    </data>

    <LinearLayout ...>
        <TextView
            android:text="@string/temperature_format(viewModel.temperature)" />
        <TextView android:text="@{viewModel.cityName}" />
        <ImageView
            android:src="@{viewModel.weatherIcon}"
            contentDescription="@{viewModel.cityName}" />
    </LinearLayout>
</layout>

Data Binding mendukung StateFlow mulai dari lifecycle 2.5.0 melalui Flow.asLiveData() atau konversi langsung. Saat menggunakan StateFlow di Data Binding, pastikan siklus hidup diatur melalui binding.lifecycleOwner. Tanpa LifecycleOwner, LiveData/StateFlow tidak akan memperbarui UI, karena Binding tidak tahu kapan pelanggan aktif.

Contoh kode: Data Binding di Kotlin dan XML

Contoh 1: Layar profil dengan Data Binding

Layar profil lengkap dengan avatar, nama, bio, dan tombol edit. ViewModel menggunakan ObservableField untuk reaktivitas.

xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="profile" type="com.example.app.ProfileViewModel" />
    </data>

    <androidx.constraintlayout...>
        <ImageView
            app:imageUrl="@{profile.avatarUrl}"
            android:contentDescription="@{profile.name}" />

        <TextView
            android:text="@{profile.name}"
            android:textStyle="bold" />

        <TextView
            android:text="@{profile.bio}"
            android:visibility="@{profile.hasBio ? View.VISIBLE : View.GONE}" />

        <Button
            android:onClick="@{() -> profile.onEdit()}"
            android:text="@string/edit" />
    </androidx.constraintlayout...>
</layout>
kotlin
class ProfileViewModel : ViewModel() {
    val name = ObservableField("Anna Petrova")
    val bio = ObservableField("Pengembang Android, 5 tahun pengalaman")
    val avatarUrl = ObservableField("https://example.com/avatar.jpg")
    val hasBio = ObservableBoolean(true)

    fun onEdit() {
        // Logika edit profil
    }
}

// Di Fragment:
val binding = FragmentProfileBinding.inflate(inflater, container, false)
binding.profile = profileViewModel
binding.lifecycleOwner = viewLifecycleOwner

Contoh 2: Formulir login dengan pengikatan dua arah

Formulir login dengan validasi bidang dan tombol masuk. Pengikatan dua arah (@={}) menyinkronkan input pengguna dengan ViewModel.

xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="login" type="com.example.app.LoginViewModel" />
    </data>

    <LinearLayout ...>
        <TextInputLayout>
            <TextInputEditText
                android:text="@{=login.email}"
                android:hint="@string/email_hint" />
        </TextInputLayout>

        <TextInputLayout>
            <TextInputEditText
                android:text="@{=login.password}"
                android:inputType="textPassword" />
        </TextInputLayout>

        <Button
            android:onClick="@{() -> login.onLogin()}"
            android:enabled="@{login.isValid}"
            android:text="@string/login" />

        <ProgressBar
            android:visibility="@{login.isLoading ? View.VISIBLE : View.GONE}" />
    </LinearLayout>
</layout>

Di XML digunakan ekspresi: @{login.isValid} untuk status tombol (aktif/tidak aktif), @{login.isLoading ? View.VISIBLE : View.GONE} untuk indikator pemuatan, @{=login.email} untuk sinkronisasi dua arah. Semua logika validasi berada di ViewModel, View hanya menampilkan status. Menurut Google (Android Guide, 2025), pendekatan ini mengurangi jumlah bug dalam logika UI sebesar 50–60%.

Pertanyaan yang Sering Diajukan

Bisakah Data Binding digunakan dengan Compose?

Tidak, Jetpack Compose adalah sistem UI mandiri dengan mekanisme reaktivitasnya sendiri (fungsi Composable + State). Data Binding ditujukan khusus untuk tata letak XML dan tidak kompatibel dengan Compose. Saat migrasi dari XML ke Compose, Data Binding tidak digunakan — sebagai gantinya digunakan mutableStateOf(), collectAsState() dan remember. Data Binding tetap relevan hanya untuk proyek yang mempertahankan tata letak XML.

Apakah Data Binding lebih lambat dari findViewById?

Pada tahap pengikatan pertama, Data Binding mencari View berdasarkan ID (seperti findViewById). Perbedaanya tidak terlihat oleh pengguna: layar biasa dengan 20–30 View terikat dalam 1–3 ms. Overhead utama Data Binding ada pada tahap kompilasi (pemrosesan ekspresi). Saat runtime, perbedaan antara Data Binding dan findViewById tidak ada untuk sebagian besar layar. Untuk RecyclerView dengan ribuan elemen, ViewBinding bisa lebih cepat karena lebih sedikit kode yang dihasilkan.

Bagaimana cara men-debug kesalahan Data Binding?

Data Binding mengompilasi ekspresi menjadi kode pada tahap build — kesalahan ditampilkan di Build Output sebagai Compilation errors dengan menunjukkan baris XML. Kesalahan umum: tipe variabel salah, null-safety (gunakan ?? untuk nilai default), tidak ada impor kelas. Aktifkan buildFeatures.dataBinding = true di build.gradle (app) dan periksa bahwa <layout> adalah tag root XML. Untuk debugging ekspresi runtime, gunakan BindingConversion dan logging di BindingAdapter.

Apa itu BindingConversion?

@BindingConversion — anotasi untuk metode statis, yang secara otomatis mengonversi tipe dalam ekspresi Data Binding. Misalnya, konversi Color Int ke ColorDrawable: @BindingConversion fun colorToDrawable(color: Int): ColorDrawable = ColorDrawable(color). Setelah itu, android:background="@{color.red}" akan bekerja secara otomatis. BindingConversion bersifat global — berlaku untuk semua ekspresi Binding di proyek.

Apakah perlu menonaktifkan Data Binding untuk build release?

Tidak, Data Binding bekerja di build release sama seperti di debug. Optimasi ProGuard/R8 dapat menghapus kelas Binding jika tidak digunakan secara langsung — tambahkan aturan: -keep class * extends android.databinding.ViewDataBinding { *; }. Mulai Android Gradle Plugin 7.0, R8 memproses Data Binding dengan benar tanpa aturan tambahan. Menonaktifkan Data Binding untuk release tidak memberikan peningkatan kinerja, tetapi merusak semua layar yang menggunakannya.

Kesimpulan

  • Data Binding — pustaka Jetpack untuk pengikatan deklaratif XML dengan data melalui ekspresi @{} dan @={}.
  • Menghasilkan kelas Binding type-safe, menghilangkan findViewById() dan ClassCastException.
  • ViewBinding — alternatif ringan tanpa ekspresi; pilih Data Binding untuk UI reaktif dan kompleks.
  • Pengikatan dua arah @={} — sinkronisasi otomatis View ↔ ViewModel untuk formulir.
  • @BindingAdapter — atribut kustom (memuat gambar, pemformatan, visibilitas).
  • Data Binding mendukung LiveData dan StateFlow secara native melalui lifecycleOwner.
  • Data Binding mengurangi kode UI sebesar 30–50% dan menurunkan jumlah bug pengikatan menjadi nol.

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga