kotlin构建MVVM应用之双向数据绑定

2020-04-15 17:10:09 浏览数 (2)

我们在构建MVVM应用的时候数据时双向流动的,比如:用户输入了数据,那么我们的model层的数据也要自动跟着更新或者我们校验了数据,是图层也要给用户反馈;网络请求完成,我们的视图层的数据也要跟着更新。

定义model层

代码语言:javascript复制
package com.xiangshike.live.model
 
 
import androidx.databinding.ObservableField
 
 
data class UserModel(
 
    val username: ObservableField<String> = ObservableField(""),
 
    val password: ObservableField<String> = ObservableField("")
 
) {
 
 override fun toString(): String {
 
        return "UserModel(username=
 }
 
}

ObservableField表示这是一个可以被观察的String类型数据,我们在用户的model层定义了两个可以被观察的变量,我们可以和视图进行双向绑定

Activity

代码语言:javascript复制
package com.xiangshike.live
 


 
import android.util.Log
 
import com.xiangshike.live.base.BaseActivity
 
import com.xiangshike.live.databinding.ActivityMainBinding
 
import com.xiangshike.live.model.UserModel
 
import kotlinx.android.synthetic.main.activity_main.*
 


 
class MainActivity : BaseActivity<ActivityMainBinding>() {
 
 private val mUserModel: UserModel by lazy { UserModel() }
 
 override fun getLayoutId(): Int = R.layout.activity_main
 
 override fun initData() {
 
        mDataBind.userModel = mUserModel
 
 }
 


 
 override fun initView() {
 
        loginBtn.setOnClickListener {
 
            login()
 
 }
 
 }
 


 
 private fun login() {
 
        val username = mUserModel.username.get().toString()
 
        val password: String = mUserModel.password.get().toString()
 
        username.isEmpty().let {
 
 when (it) {
 
 true -> usernameLayout.error = "用户名不可以为空"
 
 false -> usernameLayout.isErrorEnabled = false
 
 }
 
 }
 
        password.isEmpty().also {
 
 when (it) {
 
 true -> passwordLayout.error = "密码不可以为空"
 
 false -> passwordLayout.isErrorEnabled = false
 
 }
 
 }
 


 
        Log.d("mUserModel", "username:
 }
 
}
 
首先,我们给登录按钮增加点击事件

代码语言:javascript复制
override fun initView() {
 
        loginBtn.setOnClickListener {
 
            login()
 
 }
 
 }
 
其次,我们定义了login的方法,在这里我们实现了视图和model的双向绑定

代码语言:javascript复制
 private fun login() {
 
        val username = mUserModel.username.get().toString()
 
        val password: String = mUserModel.password.get().toString()
 
        username.isEmpty().let {
 
 when (it) {
 
 true -> usernameLayout.error = "用户名不可以为空"
 
 false -> usernameLayout.isErrorEnabled = false
 
 }
 
 }
 
        password.isEmpty().also {
 
 when (it) {
 
 true -> passwordLayout.error = "密码不可以为空"
 
 false -> passwordLayout.isErrorEnabled = false
 
 }
 
 }
 


 
        Log.d("mUserModel", "username:
 }
 

view层

代码语言:javascript复制
<?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="userModel"
 
 type="com.xiangshike.live.model.UserModel" />
 
 </data>
 


 
 <LinearLayout
 
 android:layout_width="match_parent"
 
 android:layout_height="match_parent"
 
 android:orientation="vertical">
 


 
 <com.google.android.material.textfield.TextInputLayout
 
 android:id="@ id/usernameLayout"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:layout_marginTop="66dp">
 


 
 <com.google.android.material.textfield.TextInputEditText
 
 android:id="@ id/username"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:hint="@string/username"
 
 android:singleLine="true"
 
 android:text="@={userModel.username}" />
 
 </com.google.android.material.textfield.TextInputLayout>
 


 
 <com.google.android.material.textfield.TextInputLayout
 
 android:id="@ id/passwordLayout"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:layout_marginTop="66dp"
 
 app:passwordToggleEnabled="true">
 


 
 <com.google.android.material.textfield.TextInputEditText
 
 android:id="@ id/password"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:hint="@string/password"
 
 android:inputType="textPassword"
 
 android:text="@={userModel.password}" />
 
 </com.google.android.material.textfield.TextInputLayout>
 


 
 <Button
 
 android:id="@ id/loginBtn"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:text="@string/login" />
 
 </LinearLayout>
 


 


 
</layout>
 

我们的密码框和model双向绑定

@={userModel.username} 实现的双向绑定,model<=>view的双向数据流通

代码语言:javascript复制
 <com.google.android.material.textfield.TextInputEditText
 
 android:id="@ id/username"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:hint="@string/username"
 
 android:singleLine="true"
 
 android:text="@={userModel.username}" />
 

我们输入内容,点击登录,查看控制台输出

代码语言:javascript复制
2020-04-14 11:28:00.886 10583-10583/? D/mUserModel: username:1111  password:11111

0 人点赞