当前位置: 首页 > news >正文

kotlin与MVVM的结合使用总结(三)

   在 MVVM(Model - View - ViewModel)架构中,ViewModel(VM 层)起到了连接视图(View)和数据模型(Model)的桥梁作用。它负责处理业务逻辑、管理数据状态,并将数据以一种可观察的方式提供给视图。以下将深入讲解在 Kotlin 中如何实现 MVVM 的 VM 层,并结合代码进行说明。

创建 ViewModel 类

ViewModel 类负责处理业务逻辑和管理数据状态,并将数据以 LiveData 或 StateFlow 的形式提供给视图。以下是一个使用 LiveData 的 ViewModel 示例:

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch

class UserViewModel(private val userRepository: UserRepository) : ViewModel() {
    private val _userLiveData = MutableLiveData<User>()
    val userLiveData: LiveData<User> = _userLiveData

    fun fetchUserById(id: Int) {
        viewModelScope.launch {
            try {
                // 调用仓库类的方法获取用户数据
                val user = userRepository.getUserById(id)
                // 更新 LiveData 的值
                _userLiveData.value = user
            } catch (e: Exception) {
                // 处理异常
                e.printStackTrace()
            }
        }
    }
}

在这个 ViewModel 类中:

  • _userLiveData 是一个 MutableLiveData,用于存储和更新用户数据。
  • userLiveData 是一个不可变的 LiveData,对外暴露,供视图观察。
  • fetchUserById 方法使用 viewModelScope.launch 启动一个协程,在协程中调用仓库类的 getUserById 方法获取用户数据,并将结果更新到 LiveData 中。

使用 StateFlow 替代 LiveData

除了 LiveData,还可以使用 StateFlow 来管理数据状态。StateFlow 是 Kotlin 协程库中的一个响应式数据流,它具有一些 LiveData 没有的优点,如支持背压处理和更简洁的语法。以下是使用 StateFlow 的 ViewModel 示例:

 

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class UserViewModelWithStateFlow(private val userRepository: UserRepository) : ViewModel() {
    private val _userStateFlow = MutableStateFlow<User?>(null)
    val userStateFlow: StateFlow<User?> = _userStateFlow

    fun fetchUserById(id: Int) {
        viewModelScope.launch {
            try {
                // 调用仓库类的方法获取用户数据
                val user = userRepository.getUserById(id)
                // 更新 StateFlow 的值
                _userStateFlow.emit(user)
            } catch (e: Exception) {
                // 处理异常
                e.printStackTrace()
            }
        }
    }
}

在这个 ViewModel 类中:

  • _userStateFlow 是一个 MutableStateFlow,用于存储和更新用户数据。
  • userStateFlow 是一个不可变的 StateFlow,对外暴露,供视图观察。
  • fetchUserById 方法使用 viewModelScope.launch 启动一个协程,在协程中调用仓库类的 getUserById 方法获取用户数据,并使用 emit 方法更新 StateFlow 的值。

在视图(View)中使用 ViewModel

最后,在视图(如 Activity 或 Fragment)中使用 ViewModel 获取数据并更新 UI。以下是一个使用 LiveData 的 Activity 示例:

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import com.example.mvvmexample.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var userViewModel: UserViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 获取 ViewModel 实例
        userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)

        // 观察 LiveData 的变化
        userViewModel.userLiveData.observe(this) { user ->
            // 更新 UI
            binding.tvUserName.text = user.name
            binding.tvUserAge.text = user.age.toString()
        }

        // 触发数据获取
        userViewModel.fetchUserById(1)
    }
}

在这个 Activity 中:

  • 通过 ViewModelProvider 获取 UserViewModel 的实例。
  • 使用 observe 方法观察 LiveData 的变化,当 LiveData 的值发生改变时,更新 UI。
  • 调用 fetchUserById 方法触发数据获取操作。

总结

  通过以上步骤,我们详细介绍了在 Kotlin 中实现 MVVM 架构的 VM 层的过程。ViewModel 类通过仓库类获取数据,并将数据以 LiveData 或 StateFlow 的形式提供给视图,实现了视图和数据模型的分离,提高了代码的可维护性和可测试性。同时,使用 Kotlin 协程处理异步操作,使代码更加简洁和易于理解。

这就是我对MVVM在kotlin中的使用总结

希望能对你们的学习有帮助。感谢观看!!!

 

 

相关文章:

  • 深度学习之卷积神经网络(CNN)
  • 跨国企业网络案例分析:SD-WAN智能组网
  • 用DasViewer的时候3Dtiles 转osgb 可以直接指定目标坐标系吗?
  • 电路原理(电容 集成电路NE555)
  • python学习笔记
  • ROS实践(五)机器人自动导航(robot_navigation)
  • Science Advances 视触觉传感机制的交互装置,可以实时测量来自手不同部位的分布力
  • OSPF-2 邻接建立关系
  • CentOS7安装DNS服务器bind
  • 为什么 NFS 不适合作为 TDengine 的数据存储
  • 在使用element-ui时表单的表头在切换页面时第一次进入页面容易是白色字体解决方法
  • SSR 框架是什么?
  • C#中继承的核心定义‌
  • 创新实践分享:基于边缘智能+扣子的智能取物机器人解决方案
  • PHP语言的开源贡献
  • MFCday01、模式对话框
  • 编译支持 RKmpp 和 RGA 的 ffmpeg 源码
  • 【面试】Redis
  • 数据类设计_图片类设计之5_不规则类图形混合算法(前端架构)
  • Git的详细使用方法
  • 见微知沪|科学既要勇攀高峰,又要放低身段
  • 出走的苏敏阿姨一路走到了戛纳,这块红毯因她而多元
  • 刘国中将出席第78届世界卫生大会并顺访瑞士、访问白俄罗斯
  • 南昌上饶领导干部任前公示:2人拟提名为县(市、区)长候选人
  • 韩正会见美国景顺集团董事会主席瓦格纳
  • 不是10点!乌克兰官员称尚未就俄乌谈判开始时间达成一致