kotlin基于MVVM模式的简易样例

本文介绍了一个使用Kotlin编写的MVVM架构示例,详细解释了如何通过LiveData实现数据的双向绑定,以及如何在Activity中设置ViewModel和UI组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

github大哥的

https://github.com/emedinaa/kotlin-mvvm

View
页面需要的变量


```kotlin
private val viewModel by viewModels<MuseumViewModel> {
    Injection.provideViewModelFactory()
}
//这个viewmodel说委托给viewModels类做的
private lateinit var adapter: MuseumAdapter
private lateinit var recyclerView: RecyclerView
private lateinit var layoutError: View
private lateinit var textViewError: TextView
private lateinit var layoutEmpty: View
private lateinit var progressBar: View

将viewModel的创建和UI的创建独立一个函数出来

```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_museum)
    setupViewModel()
    setupUI()
}

UI部分

private fun setupUI() {
    recyclerView = findViewById(R.id.recyclerView)
    layoutError = findViewById(R.id.layoutError)
    layoutEmpty = findViewById(R.id.layoutEmpty)
    progressBar = findViewById(R.id.progressBar)
    textViewError = findViewById(R.id.textViewError)
    adapter = MuseumAdapter(viewModel.museums.value ?: emptyList())
    //传入一个list类型的对象初始化,该list对象存在viewModel中
    recyclerView.layoutManager = LinearLayoutManager(this)
    recyclerView.adapter = adapter
}

view model部分
设置观察者,因为MVVM是双向绑定的,数据出现改变的时候会通知

private fun setupViewModel() {
    viewModel.museums.observe(this, renderMuseums)
    //传入的是一个Observer<T>类型的函数方法
    viewModel.isViewLoading.observe(this, isViewLoadingObserver)
    viewModel.onMessageError.observe(this, onMessageErrorObserver)
    viewModel.isEmptyList.observe(this, emptyListObserver)
}

observers观察者部分
有变化就改变view层,并且通知适配器更新

private val renderMuseums = Observer<List<Museum>> {
    Log.v(TAG, "data updated $it")
    layoutError.visibility = View.GONE
    layoutEmpty.visibility = View.GONE
    adapter.update(it)
}
private val isViewLoadingObserver = Observer<Boolean> {
    Log.v(TAG, "isViewLoading $it")
    val visibility = if (it) View.VISIBLE else View.GONE
    progressBar.visibility = visibility
}

private val onMessageErrorObserver = Observer<Any> {
    Log.v(TAG, "onMessageError $it")
    layoutError.visibility = View.VISIBLE
    layoutEmpty.visibility = View.GONE
    textViewError.text = "Error $it"
}

private val emptyListObserver = Observer<Boolean> {
    Log.v(TAG, "emptyListObserver $it")
    layoutEmpty.visibility = View.VISIBLE
    layoutError.visibility = View.GONE
}

如果你需要更新数据,你可以调用viewmodel中的loadMuseums方法

override fun onResume() {
    super.onResume()
    viewModel.loadMuseums()
}

override fun onDestroy() {
    super.onDestroy()
    Injection.destroy()
}

ViewModel
继承自viewModel
livedata不可修改,mutableLiveData可修改,把可修改的暴露给Activity

private val _museums = 	MutableLiveData<List<Museum>>().apply { value = emptyList() }
val museums: LiveData<List<Museum>> = _museums

private val _isViewLoading = MutableLiveData<Boolean>()
val isViewLoading: LiveData<Boolean> = _isViewLoading

private val _onMessageError = MutableLiveData<Any>()
val onMessageError: LiveData<Any> = _onMessageError

private val _isEmptyList = MutableLiveData<Boolean>()
val isEmptyList: LiveData<Boolean> = _isEmptyList
/*
如果你需要这些数据只被加载一次,可以考虑init中调用loadMuseums()。这个时候,如果你旋转屏幕,这个方法不会被调用
init {
    //loadMuseums()
}
 */
fun loadMuseums() {
    _isViewLoading.value = true
//repository是由构造函数传入的,fetchMuseum是其下的一个方法
/*
fun fetchMuseums(callback: OperationCallback<Museum>) {
    museumDataSource.retrieveMuseums(callback)
}

museumDataSoruce是一个接口,内部有fetchMuseums方法,传入一个callback
*/

    repository.fetchMuseums(object : OperationCallback<Museum> {
        override fun onError(error: String?) {
            _isViewLoading.value = false
            _onMessageError.value = error
        }

        override fun onSuccess(data: List<Museum>?) {
            _isViewLoading.value = false
            if (data.isNullOrEmpty()) {
                _isEmptyList.value = true

            } else {
                _museums.value = data
            }
        }
    })
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值