Data Binding — basis, tweerichtingsbinding in Android

Auteur: IT Sectr Gepubliceerd: 2026-02-20 Leestijd: 8 min

Data Binding — de Android Jetpack-bibliotheek die UI-componenten uit XML-layouts verbindt met gegevensbronnen in de applicatiecode via een declaratieve syntaxis. We leggen de basis uit: Data Binding elimineert de boilerplate-code findViewById() en werkt UI automatisch bij wanneer gegevens veranderen. Volgens Google (Android Developers, 2025) wordt Data Binding gebruikt in 45% van de Android-projecten en zorgt het in combinatie met LiveData of StateFlow voor volledig reactieve binding zonder handmatig abonnementenbeheer.

Belangrijkste

  • Data Binding — de Jetpack-bibliotheek voor declaratieve binding van XML-layouts met gegevensbronnen via layout-tags.
  • Tweerichtingsbinding — automatische synchronisatie van gegevens tussen View en ViewModel via @={} in XML.
  • @BindingAdapter — een aangepaste setter voor View-attributen, waarmee standaard Data Binding kan worden uitgebreid.
  • Data Binding + LiveData — reactiviteit zonder Observer: wijzigingen in LiveData werken UI automatisch bij.
  • Data Binding genereert de Binding-klasse (bijv. ActivityMainBinding) tijdens de compilatie en biedt type-safe toegang tot View.

Wat is Data Binding in Android?

Data Binding — de ondersteuningsbibliotheek (Android Jetpack), geïntroduceerd in 2015 op Google I/O en gestabiliseerd in Android Gradle Plugin 1.5. Het maakt het mogelijk om UI-componenten in XML rechtstreeks in de lay-out te binden aan gegevensbronnen (POJO, ViewModel, LiveData) zonder findViewById() aan te roepen in de code van Activity of Fragment.

Werkingsprincipe: de XML-lay-out wordt verpakt in een <layout>-tag, waarin een variabele <variable> met het gegevenstype wordt gedeclareerd. Binnen de lay-out worden gegevens ingevuld via expressies in accolades @{}. Tijdens de compilatie genereert Android Gradle Plugin de Binding-klasse (bijv. ActivityMainBinding) met directe verwijzingen naar View met de juiste typen en methoden om gegevens in te stellen.

Volgens een enquête van Android Developers (2024) vermindert Data Binding de hoeveelheid UI-code in Activity/Fragment met 30–50% door de bindingslogica naar XML te verplaatsen. Het aantal fouten met betrekking tot het verkeerde View-type (ClassCastException bij findViewById()) daalt naar nul, omdat alle typen tijdens de compilatie worden gecontroleerd.

Data Binding vs ViewBinding: wat te kiezen

ViewBinding — een lichter alternatief voor Data Binding, geïntroduceerd in Android Studio 3.6 (2020). ViewBinding genereert een Binding-klasse voor elk layout-bestand, maar zonder ondersteuning voor expressies, variabelen en reactiviteit. Vergelijking op basis van belangrijke criteria:

CriteriumData BindingViewBinding
Genereren van Binding-klasseJaJa
Expressies in XML (@{})JaNee
TweerichtingsbindingJaNee
Reactiviteit (LiveData)JaNee
@BindingAdapterJaNee
CompilatiesnelheidLangzamer (verwerking expressies)Sneller
ComplexiteitHoogLaag

Aanbeveling van Google (Android Developers, 2025): voor de meeste projecten is ViewBinding voldoende — het biedt type-safe toegang tot View zonder de overhead van Data Binding. Kies Data Binding als je nodig hebt: (1) reactieve binding met LiveData/StateFlow vanuit XML, (2) tweerichtingsbinding voor formulieren, (3) BindingAdapter voor aangepaste attributen, (4) expressies in XML voor opmaak. Bij IT Sectr gebruiken we ViewBinding voor eenvoudige schermen en Data Binding voor complexe formulieren en dashboards.

Tweerichtingsbinding: @{} en @={}

Eenrichtingsbinding (@{}) geeft gegevens door van de bron (ViewModel) naar de View. Tweerichtingsbinding (@={}) synchroniseert gegevens in beide richtingen: een wijziging in de View (tekstinvoer, schakelen van Switch) werkt de bron automatisch bij.

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

    <LinearLayout ...>
        <!-- Eenrichting: gegevens van ViewModel naar TextView -->
        <TextView
            android:text="@{viewModel.userName}" />

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

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

Voor tweerichtingsbinding moet de ViewModel ObservableField, LiveData of StateFlow gebruiken. Wanneer gegevens veranderen via gebruikersinvoer, roept Data Binding automatisch de setter van de bron aan. Belangrijk: tweerichtingsbinding werkt met attributen waarvoor @InverseBindingAdapter is gedefinieerd. Android biedt ingebouwde adapters voor: text, checked, visibility, progress, rating en andere standaardattributen.

@BindingAdapter: aangepaste attributen en converters

@BindingAdapter — een annotatie voor Kotlin-extensiefuncties, waarmee aangepaste bindingslogica voor elk View-attribuut kan worden gedefinieerd. Bijvoorbeeld het laden van een afbeelding via Glide bij het opgeven van een URL in XML, of het formatteren van een datum bij binding met TextView.

kotlin
// BindingAdapter voor het laden van afbeeldingen via 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 met meerdere attributen
@BindingAdapter("visibleGone")
fun View.setVisibleGone(visible: Boolean) {
    visibility = if (visible) View.VISIBLE else View.GONE
}

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

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

@BindingAdapter kan meerdere attributen accepteren (requireAll = true/false), waardoor waarden kunnen worden gecombineerd. Bijvoorbeeld @BindingAdapter("imageUrl", "circleCrop") — als circleCrop true is, past Glide de CircleCrop-transformatie toe. Volgens Google (Android Performance, 2024) verwerkt BindingAdapter met Glide in Data Binding tot 60 frames per seconde bij het scrollen van RecyclerView, omdat asynchroon laden de UI-thread niet blokkeert.

Data Binding met LiveData en StateFlow

Data Binding ondersteunt LiveData native sinds versie Android Architecture Components 1.0. Als de variabele in de lay-out van het type LiveData is, abonneert Binding zich er automatisch op en werkt UI bij wanneer de waarde verandert. Voor een correcte werking moet LifecycleOwner worden ingesteld in de Binding-klasse: binding.lifecycleOwner = viewLifecycleOwner.

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

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

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

// In Fragment:
val binding = FragmentWeatherBinding.inflate(inflater, container, false)
binding.viewModel = weatherViewModel
binding.lifecycleOwner = viewLifecycleOwner  // ← verplicht voor 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 ondersteunt StateFlow vanaf lifecycle 2.5.0 via Flow.asLiveData() of directe conversie. Zorg er bij gebruik van StateFlow in Data Binding voor dat de levenscyclus is ingesteld via binding.lifecycleOwner. Zonder LifecycleOwner zullen LiveData/StateFlow de UI niet bijwerken, omdat Binding niet weet wanneer de abonnee actief is.

Codevoorbeelden: Data Binding in Kotlin en XML

Voorbeeld 1: Profielscherm met Data Binding

Volledig profielscherm met avatar, naam, bio en bewerkingsknop. ViewModel gebruikt ObservableField voor reactiviteit.

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("Android-ontwikkelaar, 5 jaar ervaring")
    val avatarUrl = ObservableField("https://example.com/avatar.jpg")
    val hasBio = ObservableBoolean(true)

    fun onEdit() {
        // Logica voor profielbewerking
    }
}

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

Voorbeeld 2: Inlogformulier met tweerichtingsbinding

Inlogformulier met veldvalidatie en inlogknop. Tweerichtingsbinding (@={}) synchroniseert gebruikersinvoer met 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>

In XML worden expressies gebruikt: @{login.isValid} voor de knopstatus (actief/inactief), @{login.isLoading ? View.VISIBLE : View.GONE} voor de laadindicator, @{=login.email} voor tweerichtingssynchronisatie. Alle validatielogica leeft in de ViewModel, View toont alleen de status. Volgens Google (Android Guide, 2025) vermindert deze aanpak het aantal bugs in UI-logica met 50–60%.

Veelgestelde vragen

Kan Data Binding worden gebruikt met Compose?

Nee, Jetpack Compose is een onafhankelijk UI-systeem met een eigen reactiviteitsmechanisme (Composable-functies + State). Data Binding is uitsluitend bedoeld voor XML-lay-outs en is niet compatibel met Compose. Bij migratie van XML naar Compose wordt Data Binding niet gebruikt — in plaats daarvan worden mutableStateOf(), collectAsState() en remember toegepast. Data Binding blijft alleen relevant voor projecten die XML-lay-outs behouden.

Is Data Binding langzamer dan findViewById?

Tijdens de eerste binding zoekt Data Binding View op ID (zoals findViewById). Het verschil is niet merkbaar voor de gebruiker: een typisch scherm met 20–30 View wordt gebonden in 1–3 ms. De belangrijkste overhead van Data Binding zit in de compilatiefase (verwerking van expressies). Tijdens runtime is er voor de meeste schermen geen verschil tussen Data Binding en findViewById. Voor RecyclerView met duizenden elementen kan ViewBinding sneller zijn vanwege minder gegenereerde code.

Hoe debug ik een Data Binding-fout?

Data Binding compileert expressies naar code tijdens de build — fouten worden weergegeven in Build Output als Compilation errors met vermelding van de XML-regel. Typische fouten: onjuist variabeletype, null-veiligheid (gebruik ?? voor standaardwaarden), ontbrekende klasse-import. Schakel buildFeatures.dataBinding = true in build.gradle (app) in en controleer of <layout> de root-XML-tag is. Gebruik voor runtime-debugging BindingConversion en logging in BindingAdapter.

Wat is BindingConversion?

@BindingConversion — een annotatie voor statische methoden die automatisch typen converteert in Data Binding-expressies. Bijvoorbeeld conversie van Color Int naar ColorDrawable: @BindingConversion fun colorToDrawable(color: Int): ColorDrawable = ColorDrawable(color). Daarna werkt android:background="@{color.red}" automatisch. BindingConversion zijn globaal — ze worden toegepast op alle Binding-expressies in het project.

Moet Data Binding worden uitgeschakeld voor de release-build?

Nee, Data Binding werkt in de release-build hetzelfde als in debug. Optimalisatie door ProGuard/R8 kan Binding-klassen verwijderen als ze niet direct worden gebruikt — voeg de regel toe: -keep class * extends android.databinding.ViewDataBinding { *; }. Vanaf Android Gradle Plugin 7.0 verwerkt R8 Data Binding correct zonder extra regels. Het uitschakelen van Data Binding voor release levert geen prestatieverbetering op, maar verbreekt alle schermen die het gebruiken.

Samenvatting

  • Data Binding — de Jetpack-bibliotheek voor declaratieve binding van XML met gegevens via expressies @{} en @={}.
  • Genereert type-safe Binding-klassen, elimineert findViewById() en ClassCastException.
  • ViewBinding — licht alternatief zonder expressies; kies Data Binding voor reactieve en complexe UI.
  • Tweerichtingsbinding @={} — automatische synchronisatie View ↔ ViewModel voor formulieren.
  • @BindingAdapter — aangepaste attributen (afbeeldingen laden, opmaak, zichtbaarheid).
  • Data Binding ondersteunt native LiveData en StateFlow via lifecycleOwner.
  • Data Binding vermindert UI-code met 30–50% en brengt het aantal bindingsfouten terug tot nul.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook