DataBinding:数据绑定,即布局中的控件与可观察的数据进行绑定。
DataBinding并非是将UI逻辑搬到XML中写导致而难以调试 ,只负责绑定数据,UI控件与其需要的终态数据进行绑定。 终态数据是指UI控件直接需要的数据(UI数据),string值、int值等,而不是一段逻辑(不然就叫 LogicBinding了 ,虽然DataBinding支持逻辑表达式)。
明确了 DataBinding 的 职责边界后 应该知道了:原本的逻辑代码 该怎么写还是怎么写,只不过不再需要 textView.setText(user.name),而是直接 user.setName()。
所以 DataBinding 的本质就是 “终态数据” 与 “UI控件” 的绑定,具有以下优势:
- 无需多处调用控件,原本调用的地方只需要set数据即可
- 第一点的延伸,无需手动判空
- 第一点的延伸,完全不用写模板代码 findViewById
- 并且,引入DataBinding后,原本的 UI 逻辑无需改动,只需设置终态数据
逻辑放入xml中的写法,是不建议的。数据值应 直接反映UI控件需要的结果,而不是作为逻辑条件放在 xml 中。所以,DataBinding 不负责 UI 逻辑,逻辑原本在哪里写,现在还是在哪里写,只不过,原本调用控件实例去刷新状态的方式,现在改成了数据驱动。 这就是DataBinding 的核心目标。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #layout <?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">
<data> <variable name="user" type="String"/> </data>
<androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent">
<TextView android:text="@{user}" android:id="@+id/t1" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
<ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
<Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="click to add user" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/t1" />
<Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="click to delete user" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/button1" />
</androidx.constraintlayout.widget.ConstraintLayout> </layout>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #TestDataBindingActivity.kt class TestDataBindingActivity : AppCompatActivity() { private val userModel: UserListViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding: ActivityDatabindingBinding = DataBindingUtil.setContentView(this, R.layout.activity_databinding)
userModel.getUserLiveData().observe(this, { var s = "" for (item in it) { s = s + item.name + " / " + item.age + "\n" } binding.user = s })
userModel.getLoadingLiveData().observe(this, { findViewById<ProgressBar>(R.id.progressBar).visibility = if (it) View.VISIBLE else View.GONE }) userModel.getUserData() binding.button1.setOnClickListener { userModel.addUserData() } binding.button2.setOnClickListener { userModel.deleteUserData() } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #UserListViewModel.kt class UserListViewModel : ViewModel() {
private val userList: MutableLiveData<MutableList<User>> by lazy { MutableLiveData<MutableList<User>>() }
private val isLoading: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>() }
fun getUserLiveData(): LiveData<MutableList<User>> { return userList }
fun getLoadingLiveData(): LiveData<Boolean> { return isLoading }
fun addUserData() { val tmp = userList.value tmp?.add(User("bob", "99")) userList.value = tmp }
fun deleteUserData() { val tmp = userList.value tmp?.removeAt(0) userList.value = tmp }
fun getUserData() { isLoading.value = true UserRepository.get().getUserFromServer(object : DataCallBack<MutableList<User>> { override fun onSuccess(data: MutableList<User>) { userList.postValue(data) isLoading.postValue(false) }
override fun onFailed() { isLoading.postValue(false) } }) } }
|
参考文章:
https://juejin.cn/post/6923859213403979789
https://github.com/stewForAni/Kotlin-Jetpack