Привязка видов компоновки к компонентам архитектуры

Библиотека AndroidX включает компоненты архитектуры , которые можно использовать для разработки надежных, тестируемых и поддерживаемых приложений. Библиотека привязки данных безупречно работает с компонентами архитектуры, что еще больше упрощает разработку пользовательского интерфейса. Макеты в вашем приложении могут быть привязаны к данным в компонентах архитектуры, что помогает вам управлять жизненным циклом контроллера пользовательского интерфейса и уведомлять пользовательский интерфейс об изменениях в данных.

На этой странице показано, как включить компоненты архитектуры в ваше приложение, чтобы максимально эффективно использовать библиотеку привязки данных.

Используйте LiveData для уведомления пользовательского интерфейса об изменениях данных.

Вы можете использовать объекты LiveData в качестве источника привязки данных для автоматического уведомления пользовательского интерфейса об изменениях в данных. Дополнительную информацию об этом компоненте архитектуры см. в обзоре LiveData .

В отличие от объектов, реализующих Observable , например наблюдаемых полей , объекты LiveData знают о жизненном цикле наблюдателей, подписавшихся на изменения данных. Эти знания дают множество преимуществ, которые описаны в разделе «Преимущества использования LiveData» . В Android Studio версии 3.1 и выше вы можете заменить наблюдаемые поля объектами 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() . В следующем примере кода показано, как реализовать наблюдаемую 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);
    }
}

Дополнительные ресурсы

Чтобы узнать больше о привязке данных, обратитесь к следующим дополнительным ресурсам.

{% дословно %} {% дословно %} {% дословно %} {% дословно %}