با اشیاء داده قابل مشاهده کار کنید

مشاهده پذیری به توانایی یک شی برای آگاه کردن دیگران در مورد تغییرات داده های خود اشاره دارد. کتابخانه Data Binding به شما امکان می دهد اشیا، فیلدها یا مجموعه ها را قابل مشاهده کنید.

می‌توانید از هر شیء برای اتصال داده‌ها استفاده کنید، اما تغییر شی به‌طور خودکار باعث به‌روزرسانی رابط کاربری نمی‌شود. می‌توانید از اتصال داده استفاده کنید تا به اشیاء داده‌ای خود این توانایی را بدهید که وقتی داده‌هایشان تغییر می‌کند، به اشیاء دیگر (معروف به شنوندگان) اطلاع دهند. سه نوع کلاس قابل مشاهده وجود دارد: فیلدها ، مجموعه ها و اشیاء .

هنگامی که یکی از این اشیاء داده قابل مشاهده به UI متصل می شود و ویژگی شی داده تغییر می کند، رابط کاربری به طور خودکار به روز می شود.

زمینه های قابل مشاهده

اگر کلاس‌های شما فقط دارای چند ویژگی هستند، ممکن است ارزش تلاش برای ایجاد کلاس‌هایی که رابط Observable را پیاده‌سازی کنند، نداشته باشد. در این مورد، می‌توانید از کلاس Observable عمومی و کلاس‌های اختصاصی ابتدایی زیر برای قابل مشاهده کردن فیلدها استفاده کنید:

میدان‌های قابل مشاهده، اشیاء قابل مشاهده مستقلی هستند که دارای یک میدان واحد هستند. نسخه های اولیه از بوکس و جعبه گشایی در طول عملیات دسترسی اجتناب می کنند. برای استفاده از این مکانیسم، یک ویژگی public final در زبان برنامه نویسی جاوا یا یک ویژگی فقط خواندنی در Kotlin ایجاد کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

class User {
    val firstName = ObservableField<String>()
    val lastName = ObservableField<String>()
    val age = ObservableInt()
}

جاوا

private static class User {
    public final ObservableField<String> firstName = new ObservableField<>();
    public final ObservableField<String> lastName = new ObservableField<>();
    public final ObservableInt age = new ObservableInt();
}

برای دسترسی به مقدار فیلد، از متدهای accessor set() و get() استفاده کنید یا از نحو ویژگی Kotlin استفاده کنید:

کاتلین

user.firstName = "Google"
val age = user.age

جاوا

user.firstName.set("Google");
int age = user.age.get();

مجموعه های قابل مشاهده

برخی از برنامه ها از ساختارهای پویا برای نگهداری داده ها استفاده می کنند. مجموعه های قابل مشاهده با استفاده از یک کلید امکان دسترسی به این ساختارها را فراهم می کنند. کلاس ObservableArrayMap زمانی مفید است که کلید یک نوع مرجع باشد، مانند String ، همانطور که در مثال زیر نشان داده شده است:

کاتلین

ObservableArrayMap<String, Any>().apply {
    put("firstName", "Google")
    put("lastName", "Inc.")
    put("age", 17)
}

جاوا

ObservableArrayMap<String, Object> user = new ObservableArrayMap<>();
user.put("firstName", "Google");
user.put("lastName", "Inc.");
user.put("age", 17);

در طرح، می توانید نقشه را با استفاده از کلیدهای رشته ای پیدا کنید، همانطور که در مثال زیر نشان داده شده است:

<data>
    <import type="android.databinding.ObservableMap"/>
    <variable name="user" type="ObservableMap&lt;String, Object&gt;"/>
</data>
…
<TextView
    android:text="@{user.lastName}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
<TextView
    android:text="@{String.valueOf(1 + (Integer)user.age)}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

کلاس ObservableArrayList زمانی مفید است که کلید یک عدد صحیح باشد، به شرح زیر:

کاتلین

ObservableArrayList<Any>().apply {
    add("Google")
    add("Inc.")
    add(17)
}

جاوا

ObservableArrayList<Object> user = new ObservableArrayList<>();
user.add("Google");
user.add("Inc.");
user.add(17);

همانطور که در مثال زیر نشان داده شده است، می توانید از طریق نمایه ها به لیست دسترسی داشته باشید:

<data>
    <import type="android.databinding.ObservableList"/>
    <import type="com.example.my.app.Fields"/>
    <variable name="user" type="ObservableList&lt;Object&gt;"/>
</data>
…
<TextView
    android:text='@{user[Fields.LAST_NAME]}'
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
<TextView
    android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

اشیاء قابل مشاهده

کلاسی که رابط Observable را پیاده سازی می کند، امکان ثبت شنوندگانی را فراهم می کند که می خواهند از تغییرات ویژگی از شی قابل مشاهده مطلع شوند.

رابط Observable مکانیزمی برای اضافه کردن و حذف شنوندگان دارد، اما شما تصمیم می گیرید که اعلان ها چه زمانی ارسال شوند. برای آسان‌تر کردن توسعه، کتابخانه Data Binding کلاس BaseObservable را ارائه می‌کند که مکانیسم ثبت شنونده را پیاده‌سازی می‌کند. کلاس داده ای که BaseObservable را پیاده سازی می کند، مسئول اطلاع رسانی در زمان تغییر ویژگی ها است. برای انجام این کار، یک حاشیه نویسی Bindable به گیرنده اختصاص دهید و متد notifyPropertyChanged() را در تنظیم کننده فراخوانی کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

class User : BaseObservable() {

    @get:Bindable
    var firstName: String = ""
        set(value) {
            field = value
            notifyPropertyChanged(BR.firstName)
        }

    @get:Bindable
    var lastName: String = ""
        set(value) {
            field = value
            notifyPropertyChanged(BR.lastName)
        }
}

جاوا

private static class User extends BaseObservable {
    private String firstName;
    private String lastName;

    @Bindable
    public String getFirstName() {
        return this.firstName;
    }

    @Bindable
    public String getLastName() {
        return this.lastName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
        notifyPropertyChanged(BR.firstName);
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
        notifyPropertyChanged(BR.lastName);
    }
}

Data binding کلاسی به نام BR را در بسته ماژول ایجاد می کند که حاوی شناسه منابع مورد استفاده برای اتصال داده است. حاشیه نویسی Bindable یک ورودی در فایل کلاس BR در طول کامپایل ایجاد می کند. اگر کلاس پایه برای کلاس های داده را نمی توان تغییر داد، می توانید رابط Observable را با استفاده از یک شی PropertyChangeRegistry برای ثبت نام و اطلاع رسانی موثر به شنوندگان پیاده سازی کنید.

اشیاء آگاه از چرخه حیات

طرح‌بندی‌های موجود در برنامه شما همچنین می‌توانند به منابع اتصال داده متصل شوند که به‌طور خودکار به UI در مورد تغییرات داده‌ها اطلاع می‌دهند. به این ترتیب، اتصالات شما از چرخه حیات آگاه هستند و تنها زمانی فعال می شوند که رابط کاربری روی صفحه قابل مشاهده باشد.

Data binding از StateFlow و LiveData پشتیبانی می کند. برای اطلاعات بیشتر در مورد استفاده از LiveData در اتصال داده، به استفاده از LiveData برای اطلاع دادن به UI در مورد تغییرات داده مراجعه کنید.

از StateFlow استفاده کنید

اگر برنامه شما از Kotlin با کوروتین ها استفاده می کند، می توانید از اشیاء StateFlow به عنوان منبع اتصال داده استفاده کنید. برای استفاده از یک شی StateFlow با کلاس binding خود، یک مالک چرخه حیات را مشخص کنید تا محدوده شی StateFlow را تعریف کند. مثال زیر فعالیت را به عنوان مالک چرخه حیات پس از نمونه سازی کلاس binding مشخص می کند:

class ViewModelActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // Inflate view and obtain an instance of the binding class.
        val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)

        // Specify the current activity as the lifecycle owner.
        binding.lifecycleOwner = this
    }
}

همانطور که در Bind layout views to Architecture Components توضیح داده شد، اتصال داده به طور یکپارچه با اشیاء ViewModel کار می کند. می توانید از StateFlow و ViewModel به صورت زیر استفاده کنید:

class ScheduleViewModel : ViewModel() {

    private val _username = MutableStateFlow<String>("")
    val username: StateFlow<String> = _username

    init {
        viewModelScope.launch {
            _username.value = Repository.loadUserName()
        }
    }
}

در طرح بندی خود، همانطور که در مثال زیر نشان داده شده است، ویژگی ها و متدهای شی ViewModel خود را با استفاده از عبارات binding به نماهای مربوطه اختصاص دهید:

<TextView
    android:id="@+id/name"
    android:text="@{viewmodel.username}" />

هر زمان که مقدار نام کاربر تغییر کند، UI به طور خودکار به روز می شود.

پشتیبانی StateFlow را غیرفعال کنید

برای برنامه‌هایی که از Kotlin و AndroidX استفاده می‌کنند، پشتیبانی StateFlow به‌طور خودکار همراه با اتصال داده می‌شود. این بدان معنی است که اگر وابستگی از قبل در دسترس نباشد، وابستگی کوروتین ها به طور خودکار در برنامه شما گنجانده می شود.

می توانید با افزودن موارد زیر به فایل build.gradle خود از این قابلیت انصراف دهید:

شیار

android {
    ...
    dataBinding {
        addKtx = false
    }
}

کاتلین

android {
    ...
    dataBinding {
        addKtx = false
    }
}

همچنین، می توانید StateFlow به صورت سراسری در پروژه خود با افزودن خط زیر به فایل gradle.properties غیرفعال کنید:

شیار

android.defaults.databinding.addKtx = false

کاتلین

android.defaults.databinding.addKtx = false

منابع اضافی

برای کسب اطلاعات بیشتر در مورد اتصال داده، برای منابع اضافی به موارد زیر مراجعه کنید:

نمونه ها

Codelabs

پست های وبلاگ

{% کلمه به کلمه %} {% آخر کلمه %}