欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android Jetpack:ViewModel, LiveData & Databinding 的简单使用

程序员文章站 2022-06-07 15:14:41
...

一. 故事背景:

假设有这么一个UI,任务是点击按钮然后让N的值加1
Android Jetpack:ViewModel, LiveData & Databinding 的简单使用

二. 具体操作

① Databinding

  1. 先来看XML文件,你得先会将这个布局转成 databinding 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"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewModel" //将这个布局和一个viewModel绑定到一起
            type="XXXXXXXXXX.MyViewModel" />//这个类型XXXXX是包名
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/primaryLightColor"
        android:orientation="vertical">

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="160dp"
            android:layout_marginEnd="163dp"
            android:layout_marginBottom="317dp"
            android:text="按我让N的值增加1"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="176dp"
            android:layout_marginTop="280dp"
            android:layout_marginEnd="176dp"
            android:layout_marginBottom="67dp"
            <!---android:text="我是N的值"--> 
            android:text="@{Integer.toString(viewModel.N)}" //由于是整数,要转换一下
            app:layout_constraintBottom_toTopOf="@+id/button"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

② ViewModel

  1. 功能作用:提供给UI数据,和处理反馈数据,和Repository交互Android Jetpack:ViewModel, LiveData & Databinding 的简单使用
    如图,UI从ViewModel里获取数据来显示,ViewModel的数据来自Repository,在这里呢就是UI中的TextView要显示的数据就是N

https://codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin/#0.

  1. ViewModel的代码,UI只需要一个N,那么就设计一个N
class MyViewModel(
	//要从Repository取数据的话就加上这个参数
    /*private val myRepository: MyRepository*/
): ViewModel(){

    var n = MutableLiveData(0)//不直接用LiveData,因为LiveData的value是被保护的 protected

    val N: LiveData<Int> = n //这里就完成了给UI提供数据的功能
	
	fun plusN(){    //这里就完成了处理数据的功能
		n.value = (n.value?:0) + 1
	}
	fun XXXX(){
		XXXXXXXXXXX//这里就完成了和Repository交互的功能
	}
}
  1. 获取ViewModel
class MainActivity : AppCompatActivity(){

    private lateinit var appBarConfiguration : AppBarConfiguration

    private lateinit var viewModel: MyViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
		/*
		此处略去数据绑定的环节,和设置layout的环节
		*/
		/*
		Arg1:application: Application
		Arg2:ViewModelStoreOwner 
		*/
        viewModel = ViewModelProvider(applicationContext, this).get(MyViewModel::class.java)

}

ViewModel商店当然就是现在的MainActivity.就是说在当前MainActivity里调用ViewModelProvider(applicationContext, XXX(MainActivity的引用)).get(MyViewModel::class.java)获取到的都是一个ViewModel.下面是官方文档,仔细看看,写的挺好,关于ViewModelProvider

https://developer.android.com/reference/androidx/lifecycle/ViewModelProvider?hl=en.

③ LiveData

完成监听

class MainActivity : AppCompatActivity(){

    private lateinit var appBarConfiguration : AppBarConfiguration

    private lateinit var viewModel: MyViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
		/*
		XXXXXXXXXXXXXXX
		*/
		/*
		XXXXXXXXXXXXXXX
		XXXXXXXXXXXXXXX
		*/
        viewModel = ViewModelProvider(applicationContext, this).get(MyViewModel::class.java)
        binding = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX(不写了)
        
       //监听button的点击事件
       binding.button.setOnClickListener{
       		//调用viewModel里的数据处理方法
       		viewModel.plusN()
       }
       //监视N,当N发生改变时,要更新UI
        viewModel.N.observe(this, Observer{ 
        	binding.textView.text = Integer.toString(it)//这里的it就是N(l
        })

}