Loading... ## 1 简介 LivaData 是Jetpack提供的一种响应式编程组件。它可以包含任何类型的数据。并在数据发生变化的时候通知给观察者(通常是UI控制器)。LiveData特别适合于ViewModel结合一起使用。即ViewModel储存用户界面数据。并将其标记为LiveData。这样数据发生改变都会自动通知给UI控制器以刷新显示。 ---------- ## 2 通过UI控制器为中介的使用步骤 视图在XML布局中定义,并且这些视图的数据保存在ViewModel对象中。每个视图及其对应的之间ViewModel是一个UI控制器,它充当它们之间的中继。 ![](https://s1.ax1x.com/2020/06/04/twd8AI.png) #### 2.1. 添加依赖 它的依赖和ViewModel的依赖一样,而且它们通常也是组合使用。 在build.gradle(module:app)的dependencies块内,添加 ```gradle implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' ``` #### 2.2. 将ViewModel中的成员数据类型修改为MutableLiveData 将原本的数据类型修改为MutableLiveData的对应泛型。 ```kotlin class GameViewModel : ViewModel(){ // var word = "" var word = MutableLiveData<String>() // var score = 0 var score = MutableLiveData<Int>() init{ word.value = "" score.value = 0 } } ``` #### 2.4. 封装为LiveData 将之前的MutableLiveData设置为私有。使其对外不可见,这样外部就不可修改了。同时暴露可见但不可修改的的LiveData给外部使用。 ```kotlin class GameViewModel : ViewModel(){ private var _word = MutableLiveData<String>() private var _score = MutableLiveData<Int>() // 封装LiveData val word : LiveData<String> get() = _word val score: LiveData<Int> get() = _score init{ _word.value = "" _score.value = 0 } } ``` #### 2.5. 在UI控制器中设置观察者 将自身设置为某个LiveData的观察者,在该数据发生变化时,调用回调。 其中的viewLifecycleOwner实际是调用了GameFragment自身的getViewLifecycleOwner()方法。 ```kotlin class GameFragment : Fragment() { private lateinit var viewModel: GameViewModel override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { ....... viewModel = ViewModelProvider(this)[GameViewModel::class.java] // 添加LiveData观察者,观察者为自身。 viewModel.score.observe(viewLifecycleOwner, Observer { binding.scoreText.text = it.toString() }) ...... } } ``` ---------- ## 3 直接将LiveData绑定到view的使用 如果布局中的视图直接与ViewModel对象中的数据进行通信,而不依赖于UI控制器作为中介,则会更加简单。 ![](https://s1.ax1x.com/2020/06/04/twdN38.png) #### 3.1. 在片段对应的XML布局文件中,添加绑定变量 绑定变量名字可以自行定义,类型须为自己拓展的ViewModel。 ```xml <layout ...> <data> <variable name="gameViewModel" type="com.example.android.guesstheword.screens.game.GameViewModel" /> </data> <androidx.constraintlayout... ``` #### 3.2 在Activity/Fragment文件中将viewModel传递到数据绑定中 ```kotlin // gameViewModel为在xml布局中定义的变量名 // viewModel为在fragment/activity中关联的数据模型变量 binding.gameViewModel = viewModel ``` #### 3.3 使用侦听器绑定事件处理 在视图(xml)上直接设置侦听器。并添加事件处理。 这使得视图按钮的监听操作不必写在UI控制器里 ```xml <Button android:id="@+id/skip_button" ... android:onClick="@{() -> gameViewModel.onSkip()}" ... /> <Button android:id="@+id/correct_button" ... android:onClick="@{() -> gameViewModel.onCorrect()}" ... /> ``` #### 3.4 将LiveData添加到数据绑定 LiveData对象可用作数据绑定源,以自动将有关数据更改的信息通知给UI(xml) ```xml android:text = "@{gameViewModel.word}" ``` 要使其自动更新生效,还需将当前活动(UI控制器)设置为binding变量的生命周期所有者 ```kotlin binding.lifecycleOwner = this // 或者写为 binding.lifecycleOwner = viewLifecycleOwner ``` ---------- ## 4 参考代码 <button class="btn m-b-xs btn-dark " onclick='window.open("https://github.com/google-developer-training/android-kotlin-fundamentals-apps/blob/master/GuessTheWordDataBinding/app/src/main/java/com/example/android/guesstheword/screens/game/GameFragment.kt","_blank")'>github参考工程代码</button> 最后修改:2020 年 06 月 04 日 01 : 51 PM © 允许规范转载