将布局视图绑定到架构组件

AndroidX 库包含架构 组件,您可以 用于设计稳健、可测试且可维护的应用。 数据绑定库与架构无缝协作 用于进一步简化 进行界面开发应用中的布局 可以绑定到架构组件中的数据,这有助于您 管理界面控制器的生命周期,并在数据变化时通知界面。

本页介绍了如何将架构组件整合到您的应用中, 充分利用数据绑定库。

使用 LiveData 将数据变化通知给界面

您可以将 LiveData 对象用作 数据绑定来源,以自动通知界面有关 数据。有关此架构组件的更多信息,请参阅 LiveData 概览

与实现 Observable,例如 可观察 字段 - LiveData 对象了解订阅数据的观察者的生命周期 更改。掌握这些知识可以带来很多好处,具体请参阅 使用 LiveData 实例。 在 Android Studio 3.1 及更高版本中,您可以替换可观察字段 在数据绑定代码中与 LiveData 对象搭配使用。

如需将 LiveData 对象与绑定类一起使用,您需要指定 生命周期所有者来定义 LiveData 对象的作用域。以下 示例将 activity 指定为绑定类之后的生命周期所有者 已实例化:

Kotlin

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)
    }
}

Java

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 中转换数据:

Kotlin

class ScheduleViewModel : ViewModel() {
    val userName: LiveData

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

Java

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 组件分配给 属性。以下示例展示了如何使用 组件:

Kotlin

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
    }
}

Java

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: -> viewmodel.rememberMeChanged()}" />

使用 Observable ViewModel 更好地控制绑定适配器

您可以使用 ViewModel 用于实现 Observable 接口 通知 应用组件的数据变化,类似于使用 LiveData 对象。

在某些情况下,您可能希望使用 用于实现 ObservableViewModel 组件 使用 LiveData 对象的接口,即使您丢失了生命周期 LiveData 的管理功能。使用 ViewModel 组件, 实现 Observable 可让您更好地控制 应用。例如,此模式可让您更好地控制通知, 当数据发生变化时;还可以指定一个自定义方法来设置 属性值。

如需实现可观察的 ViewModel 组件,您必须创建一个类 继承自 ViewModel 类并实现 Observable 界面。您可以在观察器订阅或 使用 addOnPropertyChangedCallback()removeOnPropertyChangedCallback() 方法。您还可以提供在属性发生更改时运行的自定义逻辑 该 notifyPropertyChanged() 方法。以下代码示例展示了如何实现一个 ViewModel:

Kotlin

/**
 * 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)
    }
}

Java

/**
 * 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);
    }
}

其他资源

如需详细了解数据绑定,请参阅以下资源: 其他资源