使用可观察的数据对象

可观察性是指一个对象通知他人 数据变化。利用数据绑定库,你可以将对象、字段 可观察的集合。

您可以使用任何对象进行数据绑定,但修改对象不会 自动触发界面更新您可以使用数据绑定为数据 对象能够通知其他对象(称为监听器), 数据变化。可观察类有三种类型: 字段集合对象

当其中一个可观察数据对象绑定到界面,并且 数据对象发生更改时,界面会自动更新。

可观察字段

如果您的类只有少数几个属性,可能就不值得为此类 创建实现 Observable 接口。在本课中, 在这种情况下,您可以使用通用 Observable 类和以下代码 基元专用类,以使字段可观察:

可观察字段是自包含的可观察对象, 字段。原始版本可避免在访问期间装箱和开箱 操作。如需使用此机制,请在 Java 中创建一个 public final 属性 或 Kotlin 中的只读属性,如 示例:

Kotlin

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

Java

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

要访问字段值,请使用 set()get() 访问器方法 或使用 Kotlin 属性 语法

Kotlin

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

Java

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

可观察集合

某些应用使用动态结构来保存数据。可观察集合 可以使用密钥访问这些结构。通过 ObservableArrayMap 类 当键是引用类型(如 String)时非常有用,如 示例:

Kotlin

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

Java

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 类在键为整数时非常有用,如下所示:

Kotlin

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

Java

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 绑定库提供 BaseObservable 类, 实现了监听器注册机制。实现数据类 BaseObservable 负责在属性更改时发出通知。待办事项 为其分配 Bindable 注解 传递给 getter,并调用 notifyPropertyChanged() 方法,如以下示例所示:

Kotlin

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

Java

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

数据绑定在模块软件包中生成一个名为 BR 的类,其中包含 用于数据绑定的资源的 ID。Bindable 注解 在编译期间在 BR 类文件中生成一个条目。如果基类 数据类不可更改,则可以实现 Observable 接口 使用 PropertyChangeRegistry 对象来高效注册并通知监听器。

生命周期感知型对象

应用中的布局也可以绑定到自动 将数据变化通知给界面。这样,您的绑定就会 具有生命周期感知能力,并且仅在界面显示在屏幕上时触发。

数据绑定支持 StateFlowLiveData。如需详细了解 在数据绑定中使用 LiveData,请参阅使用 LiveData 通知界面有关数据的信息 更改

使用 StateFlow

如果您的应用将 Kotlin 与协程结合使用,您可以使用 StateFlow 对象作为数据绑定来源。如需搭配使用 StateFlow 对象和 绑定类,请指定生命周期所有者以定义 StateFlow 对象。以下示例将 activity 指定为 生命周期所有者:

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

将布局视图绑定到架构中所述 组件、数据绑定 可与 ViewModel 无缝搭配使用 对象的操作。您可以将 StateFlowViewModel 结合使用,如下所示:

class ScheduleViewModel : ViewModel() {

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

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

在您的布局中,将 ViewModel 对象的属性和方法分配给 相应的视图,如以下代码所示 示例:

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

每当用户的名称值发生变化时,界面都会自动更新。

停用 StateFlow 支持

对于使用 Kotlin 和 AndroidX 的应用,系统会自动支持 StateFlow 数据绑定中包含的资源。这意味着,协程依赖项 。

您可以通过将以下内容添加到 build.gradle 文件:

Groovy

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

Kotlin

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

或者,您也可以在项目中全局停用 StateFlow,方法是将 将以下代码行添加到 gradle.properties 文件中:

Groovy

android.defaults.databinding.addKtx = false

Kotlin

android.defaults.databinding.addKtx = false

其他资源

如需详细了解数据绑定,请参阅以下内容,获取更多资源:

示例

Codelab

博文