一、前言
DataBinding 是JetPack 的一部分,通常来说如果和JetPack 的其它部分结合使用效果会更好,这里对其进行记录。之前说过如果想要使数据改变的时候实时刷新到UI上面需要使用Observable 的子类才行,比如ObservableInt 。这里介绍一下如果和LiveData 、ViewMode 结合使用刷新UI的情况
二、LiveData的使用
这里实现一个功能,将LiveData 的数据绑定到UI上面,隔一段时间后更新该值,使其刷新UI
class UserViewModel: ViewModel() {
val userName = MutableLiveData<String>("默认值")
}
class MainActivity : AppCompatActivity() {
private val binding: ActivityMainBinding by lazy {
ActivityMainBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
val viewModel = ViewModelProvider(this).get(UserViewModel::class.java)
binding.viewmodel = viewModel
binding.lifecycleOwner = this
binding.root.postDelayed({
viewModel.userName.value = "更新值"
},1000)
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewmodel"
type="com.example.myapplication.UserViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/update_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@{viewmodel.userName}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="value" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
三、ViewMode的使用
以下源自官方文档
您可以使用实现 Observable 的 ViewModel 组件,向其他应用组件发出数据变化通知,这与使用 LiveData 对象的方式类似。
在某些情况下,您可能更愿意使用实现 Observable 接口的 ViewModel 组件,而不是使用 LiveData 对象,即使这样会失去对 LiveData 的生命周期管理功能也不影响。使用实现 Observable 的 ViewModel 组件可让您更好地控制应用中的绑定适配器。例如,这种模式可让您更好地控制数据更改时发出的通知,您还可以指定自定义方法来设置双向数据绑定中的属性值。
如需实现可观察的 ViewModel 组件,您必须创建一个从 ViewModel 类继承而来并实现 Observable 接口的类。您可以使用 addOnPropertyChangedCallback() 和 removeOnPropertyChangedCallback() 方法提供观察器订阅或取消订阅通知时的自定义逻辑。您还可以在 notifyPropertyChanged() 方法中提供属性更改时运行的自定义逻辑。以下代码示例展示了如何实现一个可观察的 ViewModel :
该方式和自定义实现Observable 类的方式差不多,示例如下
ViewModel
class ObservableUserModel : ViewModel(), Observable {
private val callbacks: PropertyChangeRegistry = PropertyChangeRegistry()
@Bindable
var name = "默认值"
fun updateName(newName : String){
name = newName
notifyPropertyChanged(BR.name)
}
override fun addOnPropertyChangedCallback(
callback: Observable.OnPropertyChangedCallback) {
callbacks.add(callback)
}
override fun removeOnPropertyChangedCallback(
callback: Observable.OnPropertyChangedCallback) {
callbacks.remove(callback)
}
fun notifyChange() {
callbacks.notifyCallbacks(this, 0, null)
}
fun notifyPropertyChanged(fieldId: Int) {
callbacks.notifyCallbacks(this, fieldId, null)
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="observableModel"
type="com.example.myapplication.ObservableUserModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/update_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@{observableModel.name}"
android:paddingStart="10dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="value" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val binding: ActivityMainBinding by lazy {
ActivityMainBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
val viewModel = ViewModelProvider(this).get(ObservableUserModel::class.java)
binding.observableModel = viewModel
binding.root.postDelayed({
viewModel.updateName("新值--")
},1000)
}
}
四、参考链接
- 将布局视图绑定到架构组件 ?|? Android 开发者 ?|? Android Developers
|