مقید کردن نماهای چیدمان به «مؤلفه‌های معماری»

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

این صفحه نشان می‌دهد که چگونه «مؤلفه‌های معماری» را در برنامه‌تان بگنجانید تا بیشترین بهره را از «کتابخانه اتصال داده» ببرید.

از LiveData برای مطلع کردن واسط کاربر از تغییرات داده‌ها استفاده کنید

می‌توانید از اشیاء LiveData به‌عنوان منبع اتصال داده استفاده کنید تا به‌طور خودکار تغییرات داده‌ها را به واسط کاربر اطلاع دهید. برای اطلاعات بیشتر درباره این «مؤلفه معماری»، به نمای کلی LiveData مراجعه کنید.

برخلاف اشیایی که Observable را پیاده‌سازی می‌کنند—مثل فیلدهای قابل‌مشاهده—اشیاء LiveData از چرخه حیات ناظرانی که در تغییرات داده مشترک شده‌اند مطلع هستند. این دانش مزایای زیادی را ممکن می‌سازد که در مزایای استفاده از LiveData توضیح داده شده است. در «استودیو Android» نسخه ۳.۱ و بالاتر، می‌توانید فیلدهای قابل‌مشاهده را با اشیاء LiveData در کد اتصال داده‌تان جایگزین کنید.

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

کاتلین

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.setLifecycleOwner(this)
    }
}

جاوا

class ViewModelActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Inflate view and obtain an instance of the binding class.
        UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user);

        // Specify the current activity as the lifecycle owner.
        binding.setLifecycleOwner(this);
    }
}

می‌توانید از مؤلفه ViewModel استفاده کنید، همان‌طور که در بخش زیر توضیح داده شده است، تا داده‌ها را به چیدمان متصل کنید. در مؤلفه ViewModel، می‌توانید از شیء LiveData برای تبدیل داده‌ها یا ادغام چندین منبع داده استفاده کنید. مثال زیر نشان می‌دهد که چگونه داده‌ها را در ViewModel تبدیل کنید:

کاتلین

class ScheduleViewModel : ViewModel() {
    val userName: LiveData

    init {
        val result = Repository.userName
        userName = Transformations.map(result) { result -> result.value }
    }
}

جاوا

class ScheduleViewModel extends ViewModel {
    LiveData username;

    public ScheduleViewModel() {
        String result = Repository.userName;
        userName = Transformations.map(result, result -> result.value);
    }
}

استفاده از ViewModel برای مدیریت داده‌های مرتبط با میانای کاربر

«کتابخانه اتصال داده» به‌طور یکپارچه با مؤلفه‌های ViewModel کار می‌کند. ViewModel داده‌هایی را که طرح‌بندی مشاهده می‌کند و به تغییرات آن واکنش نشان می‌دهد، نمایش می‌دهد. استفاده از مؤلفه‌های ViewModel با «کتابخانه اتصال داده» به شما امکان می‌دهد منطق میانای کاربر را از چیدمان‌ها خارج کنید و به مؤلفه‌ها منتقل کنید که آزمایش کردن آن‌ها آسان‌تر است. «کتابخانه اتصال داده» تضمین می‌کند که نماها درصورت نیاز به منبع داده متصل و از آن جدا شوند. بخش عمده کار باقی‌مانده این است که مطمئن شوید داده‌های درست را نمایش می‌دهید. برای اطلاعات بیشتر درباره این «مؤلفه معماری»، به نمای کلی ViewModel مراجعه کنید.

برای استفاده از مؤلفه ViewModel با «کتابخانه اتصال داده»، باید مؤلفه‌تان را نمونه‌سازی کنید—که از کلاس ViewModel ارث‌بری می‌کند، نمونه‌ای از کلاس اتصال خود را دریافت کنید، و مؤلفه ViewModel خود را به ویژگی‌ای در کلاس اتصال اختصاص دهید. مثال زیر نحوه استفاده از مؤلفه با کتابخانه را نشان می‌دهد:

کاتلین

class ViewModelActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // Obtain the ViewModel component.
        val userModel: UserModel by viewModels()

        // Inflate view and obtain an instance of the binding class.
        val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)

        // Assign the component to a property in the binding class.
        binding.viewmodel = userModel
    }
}

جاوا

class ViewModelActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Obtain the ViewModel component.
        UserModel userModel = new ViewModelProvider(this).get(UserModel.class);

        // Inflate view and obtain an instance of the binding class.
        UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user);

        // Assign the component to a property in the binding class.
        binding.viewmodel = userModel;
    }
}

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

<CheckBox
    android:id="@+id/rememberMeCheckBox"
    android:checked="@{viewmodel.rememberMe}"
    android:onCheckedChanged="@{() -> viewmodel.rememberMeChanged()}" />

برای کنترل بیشتر بر آداپتورهای اتصال، از Observable ViewModel استفاده کنید

می‌توانید از مؤلفه ViewModel که میانای Observable را پیاده‌سازی می‌کند برای مطلع کردن دیگر مؤلفه‌های برنامه از تغییرات داده‌ها استفاده کنید، مشابه نحوه استفاده از شیء LiveData.

موقعیت‌هایی وجود دارد که ممکن است ترجیح دهید از مؤلفه ViewModel که میانای Observable را پیاده‌سازی می‌کند به‌جای استفاده از اشیاء LiveData استفاده کنید، حتی اگر قابلیت‌های مدیریت چرخه حیات LiveData را ازدست بدهید. استفاده از مؤلفه ViewModel که Observable را پیاده‌سازی می‌کند، کنترل بیشتری بر آداپتورهای اتصال در برنامه‌تان به شما می‌دهد. برای مثال، این الگو کنترل بیشتری بر اعلان‌ها هنگام تغییر داده‌ها به شما می‌دهد؛ همچنین به شما امکان می‌دهد روشی سفارشی برای تنظیم مقدار یک ویژگی در اتصال داده دوطرفه مشخص کنید.

برای پیاده‌سازی مؤلفه ViewModel قابل‌مشاهده، باید کلاسی ایجاد کنید که از کلاس ViewModel ارث‌بری کند و میانای Observable را پیاده‌سازی کند. می‌توانید منطق سفارشی ارائه دهید وقتی ناظری بااستفاده از روش‌های addOnPropertyChangedCallback() و removeOnPropertyChangedCallback() در اعلان‌ها مشترک می‌شود یا اشتراکش را لغو می‌کند. همچنین می‌توانید منطق سفارشی ارائه دهید که هنگام تغییر ویژگی‌ها در روش notifyPropertyChanged() اجرا می‌شود. نمونه کد زیر نحوه پیاده‌سازی یک observable را نشان می‌دهد ViewModel:

کاتلین

/**
 * A ViewModel that is also an Observable,
 * to be used with the Data Binding Library.
 */
open class ObservableViewModel : ViewModel(), Observable {
    private val callbacks: PropertyChangeRegistry = PropertyChangeRegistry()

    override fun addOnPropertyChangedCallback(
            callback: Observable.OnPropertyChangedCallback) {
        callbacks.add(callback)
    }

    override fun removeOnPropertyChangedCallback(
            callback: Observable.OnPropertyChangedCallback) {
        callbacks.remove(callback)
    }

    /**
     * Notifies observers that all properties of this instance have changed.
     */
    fun notifyChange() {
        callbacks.notifyCallbacks(this, 0, null)
    }

    /**
     * Notifies observers that a specific property has changed. The getter for the
     * property that changes must be marked with the @Bindable annotation to
     * generate a field in the BR class to be used as the fieldId parameter.
     *
     * @param fieldId The generated BR id for the Bindable field.
     */
    fun notifyPropertyChanged(fieldId: Int) {
        callbacks.notifyCallbacks(this, fieldId, null)
    }
}

جاوا

/**
 * A ViewModel that is also an Observable,
 * to be used with the Data Binding Library.
 */
class ObservableViewModel extends ViewModel implements Observable {
    private PropertyChangeRegistry callbacks = new PropertyChangeRegistry();

    @Override
    protected void addOnPropertyChangedCallback(
            Observable.OnPropertyChangedCallback callback) {
        callbacks.add(callback);
    }

    @Override
    protected void removeOnPropertyChangedCallback(
            Observable.OnPropertyChangedCallback callback) {
        callbacks.remove(callback);
    }

    /**
     * Notifies observers that all properties of this instance have changed.
     */
    void notifyChange() {
        callbacks.notifyCallbacks(this, 0, null);
    }

    /**
     * Notifies observers that a specific property has changed. The getter for the
     * property that changes must be marked with the @Bindable annotation to
     * generate a field in the BR class to be used as the fieldId parameter.
     *
     * @param fieldId The generated BR id for the Bindable field.
     */
    void notifyPropertyChanged(int fieldId) {
        callbacks.notifyCallbacks(this, fieldId, null);
    }
}

منابع بیشتر

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