MVVM基础篇

2021-01-29  本文已影响0人  Method

Android 官方推荐的应用架构如下图:


mvvm.png

MVP、MVVM区别

MVP 和 MVVM 都是为了解决界面和数据的分离问题,两者只是采用了不同的实现方案。MVP 之间的交互主要是通过接口实现的,其主要弊端就是需要编写大量接口。而 MVVM 则是通过数据绑定的方式实现交互,虽然其实现需要依赖具体的一些框架工具,但明显大大减少了开发者需要编写的代码量。

创建一个MVVM登录案例

xml

<?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"
            type="com.example.hellokotlin.structure.mvvm.LoginViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <EditText
            android:id="@+id/editTextTextPersonName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="2dp"
            android:layout_marginLeft="2dp"
            android:layout_marginBottom="47dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:text="@={viewModel.phone}"
            app:layout_constraintBottom_toTopOf="@+id/editTextTextPersonName2"
            app:layout_constraintStart_toStartOf="@+id/editTextTextPersonName2" />

        <EditText
            android:id="@+id/editTextTextPersonName2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="207dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:text="@={viewModel.pwd}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="78dp"
            android:text="Button"
            android:onClick="@{()->viewModel.login()}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/editTextTextPersonName2" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View层

/**
 * View 层
 * 通过viewmodel livedata 监听数据变化 显示
 */
class LoginActivity:AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        val loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java]
        loginViewModel.loginResult.observe(this, Observer {
            if(it){
                println("登录成功")
                finish()
            }else{
                println("登录失败")
            }
        })

    }
}

viewmodel层

/**
 * viewModel层
 */
class LoginViewModel : ViewModel() {
    val phone = ObservableField<String>()
    val pwd = ObservableField<String>()
    val repository = LoginRepository()

    private val _loginResult by lazy {
        MutableLiveData<Boolean>()
    }

    //保证其他类只能监听 不能更改
    val loginResult: LiveData<Boolean> = _loginResult
    fun login() {
        if (phone.get().isNullOrEmpty()) {
            println("请输入手机号")
            return
        }

        if (pwd.get().isNullOrEmpty()) {
            println("请输入密码")
            return
        }
        _loginResult.value = repository.loginFromService(phone.get(), pwd.get())
    }
}

model层

/**
 * 数据仓库
 * 1.可以从网络获取数据
 * 2.可以从数据库获取数据等
 */
class LoginRepository {
    fun loginFromService(phone: String?, pwd: String?):Boolean {
        return Random.nextBoolean()
    }
}
上一篇下一篇

猜你喜欢

热点阅读