Two-Way Binding: bu nədir, Android və iOS-da ikitərəfli məlumat bağlaması

Müəllif: IT Sectr Dərc olunub: 2026-02-20 Oxuma vaxtı: 12 dəq

Two-Way Binding — ikitərəfli məlumat bağlaması, modeli və təqdimatı mobil tətbiqlərdə avtomatik sinxronlaşdıran mexanizm haqqında məlumat əldə edin. findViewById vasitəsilə əl ilə UI yeniləməsindən fərqli olaraq, bağlama mexanizmi həm istifadəçi daxiletməsi dəyişdikdə modeli, həm də məlumat dəyişdikdə təqdimatı yeniləyir. Google I/O 2024 məlumatlarına görə, bağlama Android və iOS layihələrində şablon UI kodunu 30–50% azaldır. Bu yanaşma Jetpack Compose və SwiftUI-dən Flutter və React Native-ə qədər freymvorklarda tətbiq olunur.

Əsas məqamlar

  • Two-Way Binding — model (ViewModel) və təqdimat (View) arasında məlumatları hər iki istiqamətdə avtomatik sinxronlaşdıran mexanizm.
  • Android-də @BindingAdapter@= vasitəsilə DataBinding-də, iOS-da isə @Binding vasitəsilə SwiftUI-də tətbiq olunur.
  • Google məlumatlarına görə, DataBinding findViewById vasitəsilə əl ilə bağlama ilə müqayisədə UI kodunun həcmini 30–50% azaldır.
  • Əsas təhlükə — dəyişiklik dinləyicilərinin səhv qurulması halında sonsuz yeniləmə dövrələri.
  • Müasir inkişafda aşkar hadisələrlə birtərəfli axına (UDF) üstünlük verilir, Two-Way Binding isə giriş formaları üçün nöqtəvi şəkildə tətbiq olunur.

Two-Way Binding nədir?

Two-Way Binding (ikitərəfli məlumat bağlaması) — memarlıq mexanizmi olub, məlumat modelindəki dəyişikliklər avtomatik olaraq istifadəçi interfeysində əks olunur və UI-dəki dəyişikliklər dərhal modeli yeniləyir. Məlumat axınının yalnız modeldən təqdimata getdiyi birtərəfli bağlamadan fərqli olaraq, ikitərəfli bağlama hər yeniləməni əl ilə kodlaşdırmadan qapalı sinxronizasiya dövrəsi yaradır.

Android Developers Blog (2023) məlumatlarına görə, 2015-ci ildə təqdim edilmiş DataBinding kitabxanası kommersiya Android tətbiqlərinin 42%-də istifadə olunur. Mexanizm xüsusilə giriş formalarında — mətn sahələri, açarlar, sürgülər və qeyd qutuları — tələb olunur, burada istifadəçi daxiletməsi dərhal modeldə, proqram dəyişiklikləri isə UI-də əks olunmalıdır. Bütün bu ssenarilərdə tərtibatçı bir bağlama yazır, «dinləyici + setter» cütü əvəzinə.

IT Sectr-də 2017-ci ildən layihələrdə ikitərəfli bağlamadan istifadə edirik və onu şüurlu şəkildə tətbiq etməyi tövsiyə edirik: sadə giriş sahələri üçün, lakin asılılıqları olan mürəkkəb vəziyyətlər üçün yox.

İkitərəfli bağlama necə işləyir?

Two-Way Binding mexanizmi üç əsas elementə əsaslanır: müşahidə olunan sahə (observable), dəyişiklik dinləyicisi (listener)əks sinxronizasiya mexanizmi. İstifadəçi EditText sahəsinə mətn daxil etdikdə, sistem TextWatcher hadisəsini ələ keçirir, yeni dəyəri bağlı dəyişənə yazır və dəyişən koddan dəyişibsə, UI-ni yenidən çəkmək zərurəti barədə xəbərdar edir.

DataBinding kitabxanası Android-də kompilyasiya mərhələsində bütün bağlama məntiqini ehtiva edən Binding sinfi yaradır. @={variable} atributu olan hər View üçün inaktivasiya ilə setter + getter cütü yaradılır. SwiftUI-də eyni işi Combine mexanizmi vasitəsilə dəyəri sinxronlaşdıran @Binding propertyWrapper görür. SwiftUI dəyişiklikləri @Published xüsusiyyətləri vasitəsilə izləyir və bağlı dəyişənin hər dəyişməsində View-ni avtomatik yenidən çəkir.

WWDC Session 10033 (2023) məlumatlarına görə, SwiftUI-də @Binding mexanizmi giriş sahələrinin sinxronizasiyasında saniyədə 60 kadr emal edir ki, bu da onu gecikməsiz interaktiv formalar üçün yararlı edir. Hər iki freymvorkda Two-Way Binding Observer nümunəsi üzərində sintaktik şəkərdir, abunəliyi və bildirişi avtomatlaşdırır.

Android-də Two-Way Binding: DataBinding və Jetpack Compose

Android-də ikitərəfli bağlama iki variantda mövcuddur: klassik XML-DataBinding @={} atributu vasitəsilə və Jetpack Compose ikitərəfli state-istinadları vasitəsilə. Hər iki yanaşma eyni problemi — UI və modelin sinxronizasiyasını həll edir, lakin sintaksis və tətbiq sahəsinə görə fərqlənir.

@BindingAdapter və @= ilə DataBinding

XML işarələməsində ikitərəfli bağlama @={variable.property} sintaksisi ilə işarələnir — qıvrım mötərizələr daxilindəki bərabər işarəsi onu birtərəfli @{variable}-dən fərqləndirir. Xüsusi View-lər üçün inverse atributunu göstərən @BindingAdapter annotasiyası tələb olunur.

XML
<layout>
    <data>
        <variable name="viewModel" type="com.example.LoginViewModel" />
    </data>
    <EditText
        android:text="@{viewModel.email}" />
    <CheckBox
        android:checked="@{viewModel.agreeToTerms}" />
</layout>

Nümunə email və qeyd qutusu olan ən sadə formanı göstərir — hər iki sahə ikitərəfli bağlamadan istifadə edir ki, bu da Activity kodunda TextWatcher və OnCheckedChangeListener yazmaq ehtiyacını aradan qaldırır. İstifadəçi tərəfindən mətn dəyişdirildikdə viewModel.email sahəsi avtomatik yenilənir.

Kotlin
@BindingAdapter("app:rating")
fun RatingBar.setRating(rating: Float) {
    if (rating != this.rating) {
        this.rating = rating
    }
}

@InverseBindingAdapter("app:rating")
fun RatingBar.getRating(): Float = this.rating

@BindingAdapter("app:ratingAttrChanged")
fun RatingBar.setListeners(
    listener: InverseBindingListener?
) {
    this.onRatingBarChangeListener =
        RatingBar.OnRatingBarChangeListener { _, _, _ -> listener?.onChange() }
}

RatingBar üçün xüsusi BindingAdapter bir cüt annotasiyadan istifadə edir — @BindingAdapter və @InverseBindingAdapter — DataBinding kitabxanasının View-dən dəyəri necə oxuyacağını (əks əlaqə) və View-ə necə yazacağını (birbaşa əlaqə) bilməsi üçün. AttrChanged suffiksi olan üçüncü adapter sistemi istifadəçi tərəfindən dəyərin dəyişməsi barədə xəbərdar edir.

Jetpack Compose-da Two-Way Binding

Jetpack Compose @={} sintaksisini dəstəkləmir, lakin mutableStateOf və setter funksiyasının aşkar ötürülməsi vasitəsilə oxşar mexanizm təmin edir. Compose-da ikitərəfli bağlama State və callback funksiyasının (value, onValueChange) uşaq komponentlərə ötürülməsi əsasında qurulur.

Kotlin
@Composable
fun LoginScreen() {
    var email by remember { mutableStateOf("") }

    OutlinedTextField(
        value = email,
        onValueChange = { email = it },
        label = { Text("Email") }
    )
}

@Composable
fun CustomRatingBar(
    rating: Float,
    onRatingChange: (Float) -> Unit
) {
    Slider(
        value = rating,
        onValueChange = onRatingChange,
        valueRange = 0f..5f
    )
}

Compose-da ikitərəfli əlaqə state + callback cütü vasitəsilə imitasiya olunur — valideyn cari dəyəri və onun yenilənmə funksiyasını ötürür, uşaq komponent istifadəçi qarşılıqlı əlaqəsi zamanı callback-i çağırır. Bu yanaşma məlumat axınının istiqamətini aşkar şəkildə göstərir ki, bu da DataBinding-in gizli sinxronizasiyası ilə müqayisədə debug etməni asanlaşdırır.

iOS-da Two-Way Binding: SwiftUI-də @Binding

SwiftUI-də ikitərəfli bağlama valideyn View-ə aid məlumat mənbəyinə read-write istinad yaradan @Binding propertyWrapper vasitəsilə həyata keçirilir. @Binding dəyəri müstəqil saxlamır — valideynin @State və ya @StateObject vasitəsilə oxuyur və yazır.

Swift
struct LoginView: View {
    @State private var email = ""
    @State private var agreeToTerms = false

    var body: some View {
        Form {
            TextField("Email", text: $email)
            Toggle("Şərtlərlə razıyam", isOn: $agreeToTerms)
            ChildRatingView(rating: $rating)
        }
    }
}

struct ChildRatingView: View {
    @Binding var rating: Double

    var body: some View {
        Slider(value: $rating, in: 0...5)
    }
}

Dəyişən adı qarşısındakı $ simvolu Binding istinadı yaradır: $email Binding<String> tipinə malikdir, String yox. SwiftUI TextField-də mətn dəyişməsini Combine mexanizmi vasitəsilə email xüsusiyyətinin yenilənməsi ilə avtomatik əlaqələndirir. Valideyn View uşaq komponentə öz @State-nə Binding ötürür ki, bu da deleqatlar və ya callback-lər olmadan iyerarxiyanın istənilən səviyyəsindən vəziyyəti dəyişməyə imkan verir.

Apple WWDC 2023 məlumatlarına görə, SwiftUI yenidənçəkmələri minimuma endirmək üçün diffing alqoritmindən istifadə edir: əgər @Binding dəyəri dəyişibsə, lakin View bu dəyərdən asılı deyilsə, yenidənçəkmə baş vermir. Bu, UIKit ilə müqayisə olunan performans təmin edir (ProMotion displeylərində 120 FPS-ə qədər).

Two-Way Binding vs UDF: nə vaxt hansı seçilməlidir

İkitərəfli bağlama və birtərəfli məlumat axını (UDF) arasında seçim mobil inkişafda əsas memarlıq qərarlarından biridir. Two-Way Binding forma lokal vəziyyətləri üçün optimaldır, burada istifadəçinin hər addımı əlavə kod olmadan dərhal modeldə əks olunmalıdır. UDF tətbiqin qlobal vəziyyəti üçün üstünlük təşkil edir, burada dəyişikliklərin proqnozlaşdırıla bilməsi inkişaf sürətindən daha vacibdir.

MeyarTwo-Way BindingUDF
Kodun həcmi formada1 sətir (@={} atributu)5–7 sətir (State, Intent, Reducer)
Məlumat axınının debug-uÇətin (kim dəyişdi — UI yoxsa kod?)Asan (bütün dəyişikliklər Intent vasitəsilə)
PerformansYüksək (native sinxronizasiya)Orta (Reducer + Redux təbəqəsi)
ÖlçeklenebilirlikMürəkkəb formalarda validasiya ilə azalırEkran sayı ilə artır
Vəziyyətlərin proqnozlaşdırılmasıAşağı (dövrlərdən yan təsirlər)Yüksək (reduiser — yeganə həqiqət mənbəyi)

Tövsiyə: sadə giriş sahələri (mətn, qeyd qutuları, açarlar) üçün 3–5 sahəli formalarda mürəkkəb validasiya olmadan Two-Way Binding istifadə edin. Qlobal vəziyyəti, şəbəkə sorğuları və asılı sahələri olan ekranlar üçün birtərəfli axın və aşkar hadisə emalı ilə UDF tətbiq edin. IT Sectr-də hər iki yanaşmanı birləşdiririk: Two-Way Binding forma daxilində, UDF naviqasiya və biznes məntiqi üçün.

İkitərəfli bağlamada tipik səhvlər

Sonsuz yeniləmə dövrü — Two-Way Binding istifadə edərkən ən çox rast gəlinən problem. Dövr modelin dəyişməsi UI yeniləməsinə səbəb olduqda yaranır ki, bu da modeli yenidən dəyişir. DataBinding-də bu, @InverseBindingAdapter-də getter setter çağırışından dərhal sonra yeni dəyər qaytardıqda baş verir. Həll — əks yazmadan əvvəl dəyərin dəyişib-dəyişmədiyini yoxlamaq (guard şərti).

İkinci geniş yayılmış səhv — hesablanmış sahələrin bağlanması. Əgər sahə başqa sahədən asılıdırsa (məsələn, ümumi dəyər = qiymət × miqdar), ikitərəfli bağlama uyğunsuz vəziyyətə səbəb ola bilər. Məsələn, istifadəçi miqdarı dəyişir, dəyərin yenidən hesablanması tetiklenir, bu da miqdarı yenidən dəyişir. Hesablanmış sahələr üçün Flow və ya Combine ilə birtərəfli bağlamadan istifadə edin.

Üçüncü səhv — LifecycleOwner olmadan Observable sahələrin bağlanması. Android DataBinding-də bindiqə LifecycleOwner ötürülməsi tələb olunur, əks halda müşahidəçilər Activity məhv edildikdə təmizlənməyəcək, bu da yaddaş sızmasına səbəb olur. Həmişə fraqmentlərdə viewLifecycleOwner, Activity-də isə this ötürün.

Google Issue Tracker (2024) məlumatlarına görə, DataBinding üzrə səhv hesabatlarının təxminən 15%-i tsiklik yeniləmələrlə bağlıdır. Diaqnostika üçün Android Studio Layout Inspector istifadə edin — o, ekrandakı bütün bağlamaların cari dəyərlərini göstərir ki, bu da sonsuz dövrənin mənbəyini tapmağı asanlaşdırır.

Tez-tez verilən suallar

İkitərəfli bağlama birtərəfli bağlamadan nə ilə fərqlənir?

Birtərəfli bağlama (One-Way Binding) məlumatları yalnız modeldən təqdimata ötürür — model dəyişdikdə UI yenilənir, lakin istifadəçi daxiletməsi modeli birbaşa dəyişmir. Two-Way Binding məlumatları hər iki istiqamətdə sinxronlaşdırır: UI-də dəyişiklik avtomatik olaraq modeli yeniləyir və əksinə. DataBinding sintaksisində fərq @{} (One-Way) və @={} (Two-Way) simvolları ilə göstərilir.

Two-Way Binding nə vaxt istifadə edilməməlidir?

Asılı sahələri, hesablanmış dəyərləri və ya xüsusi validasiyası olan mürəkkəb formalar üçün ikitərəfli bağlamadan istifadə etməyin — bu ssenarilərdə məlumat axını proqnozlaşdırıla bilməz. Həmçinin hər elementin bindiq olduğu çox sayda elementli RecyclerView siyahılarında ondan çəkinin: çoxsaylı müşahidəçilər səbəbindən performans aşağı düşür. Hadisələrin Intent emalı ilə birtərəfli axını olan UDF daha yaxşı miqyaslanır.

Jetpack Compose ikitərəfli bağlamanı dəstəkləyir?

Jetpack Compose daxili @={} sintaksisinə malik deyil, lakin ikitərəfli sinxronizasiya State + callback (onValueChange) cütü vasitəsilə həyata keçirilir. Valideyn cari dəyəri (State) və yeniləmə funksiyasını ötürür, uşaq komponent dəyişiklik zamanı callback-i çağırır. Bu aşkar bağlamadır, gizli deyil — məlumat axını görünən və izlənilə bilən qalır.

DataBinding-də sonsuz dövrəni necə debug etmək olar?

DataBinding-də dövrələri debug etmək üçün Android Studio Layout Inspector istifadə edin — o, ekrandakı bütün bağlı dəyişənlərin cari dəyərlərini göstərir. @InverseBindingAdapter-də loglama əlavə edin və getter-in yenicə yazılmış dəyərdən fərqli dəyər qaytarmadığını yoxlayın. Standart həll — əks yazmadan əvvəl guard şərti: if (newValue != currentValue).

Flutter-da Two-Way Binding varmı?

Flutter-da daxili ikitərəfli bağlama yoxdur, lakin TextEditingController və onChanged callback-i vasitəsilə emulyasiya olunur. StatefulWidget üçün tərtibatçı əl ilə nəzarətçinin dəyişikliklərinə abunə olur və modeli yeniləyir. Provider və Riverpod-da ikitərəfli sinxronizasiya Selector vasitəsilə qurulur, o, model dəyişdikdə vidjeti yenidən qurur və istifadəçi daxiletməsi zamanı callback-i çağırır.

Nəticə

  • Two-Way Binding — model və təqdimat arasında avtomatik ikitərəfli sinxronizasiya mexanizmi, dinləyicilərin və setterlərin əl ilə yazılması ehtiyacını aradan qaldırır.
  • Android-də @={} sintaksisi və @BindingAdapter/@InverseBindingAdapter annotasiyaları ilə DataBinding vasitəsilə tətbiq olunur.
  • iOS SwiftUI valideynin @State-nə read-write istinad yaradan @Binding propertyWrapper təmin edir.
  • DataBinding UI kodunun həcmini 30–50% azaldır, lakin sonsuz dövrələr yarandıqda debug-u çətinləşdirir.
  • 3–5 sahəli formalar üçün Two-Way Binding səmərəlidir; qlobal vəziyyət və mürəkkəb validasiya üçün UDF seçin.
  • Jetpack Compose-da ikitərəfli əlaqə State + onValueChange callback-i vasitəsilə imitasiya olunur, aşkar məlumat axınını qoruyur.
  • Əsas risklər — tsiklik yeniləmələr, hesablanmış sahələrin bağlanması və LifecycleOwner olmadıqda yaddaş sızmaları.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun