Kotlin_MVVM

简单记录Kotlin 下使用MVVM的例子。

实现:模拟数据变化, 更新UI (两个TextView, 一个显示名字,一个显示计数)

Kotlin_MVVM_第1张图片

一、app 目录build.grade 启动 dataBinding 

android {
    //...
    dataBinding {
        enabled = true
    }
}

二、创建UserData (M) 和UserViewModel

class UserViewModel : BaseObservable {
    private var userData = UserData(this)

    constructor()

    //e: ����: Bindable must be on a member in an Observable class. UserViewModel is not Observable
    @Bindable
    fun getUserName(): String? {
        return userData.getCurUserName()
    }

    @Bindable
    fun getCount(): String {
        return userData.getCurrCount().toString()
    }


    fun changeUserName() {
        notifyPropertyChanged(BR.userName)
        notifyPropertyChanged(BR.count)
    }
}

1. UserViewModel: 主要提供两个Bindable 函数, 用于布局文件(V- view); 

                           changeUserName() 通知UI 数据已经变化,请更新UI

需要注意: Bindable 修饰函数(实际上为变量的get 方法), 需要所在的ViewModel 继承 BaseObservable,

否则,会报错:

 Bindable must be on a member in an Observable class. UserViewModel is not Observable

此外,也可以通过定义Observable 的变量,实现当数据变化时,自动更新UI, 则不需要手动调用notifyPropertyChanged 

    var userName = ObservableField()
    userName.set(null)
    userName.set("Xiaoming")

 创建UserData:

class UserData {
    private var userNameList = mutableListOf("ZhangSan", "LiSi", "WangWu"
        , "ZhaoLiu", "YangBa", "SunJiu")
    private var curUserNameIndex = 0
    private var userViewModel: UserViewModel
    private var changeCount = 0
    private val maxCount = 20

    constructor(userViewModel: UserViewModel) {
        this.userViewModel = userViewModel
        //模拟数据变化
        simulateDataChange()
    }

    fun getCurUserName() : String ?{
        return userNameList[curUserNameIndex]
    }

    fun getCurrCount () : Int {
        return changeCount
    }

    private fun simulateDataChange() {
        Thread{
           for ( count in 0 until maxCount) {
               Thread.sleep(2000)
               changeCount++
               curUserNameIndex++
               if (curUserNameIndex >= userNameList.size) {
                   curUserNameIndex = 0
               }
               this.userViewModel.changeUserName()
           }
        }.start()
    }
}

 1. UserData:  提供用户名字(username) 和 当前计数(changeCount), 启动线程,每隔一秒更新数据(即curUserNameIndex),

并且调用 ViewModel 的 changeUserName() 告知数据变化了

其中,UserData / UserViewModel 相互持有引用,实际上,UserData(Model) 不需要持有ViewModel

 

三、布局文件 (V)




    
        
    

    

        

        

    

其中, 

1. 布局文件为    标签 

2. 标签定义引用的 ViewModel 类型和变量, 使用 variable 标签包裹,其中name 为变量名,type为类所在的包

        
如果想要引用Android 自带VIEW 的API, 例如 View.VISIBLE, 只需import 这个类
​​​​​​​

3. 使用到viewmodel的地方:  android:text="@{userViewModel.userName}"

表示显示的文本,是引用 userViewModel 里面的 getUserName()的返回值 (省略了get)

 

四、 Activity 中调用

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        var dataBinding =
            DataBindingUtil.setContentView(this, R.layout.activity_main)
        var userViewModel = UserViewModel()
        dataBinding.userViewModel = userViewModel

    }
}

主要根据 DataBindingUtils 进行setContentView  (取代了之前的setContentView(R.layout.activity_main),

并且返回一个布局文件对应的 Binding 类型,  作用是设置布局文件里面的 ViewModel 变量

你可能感兴趣的:(Kotlin,Android,Basic)