https://github.com/emedinaa/kotlin-mvvm
View
页面需要的变量
private val viewModel by viewModels
__}
//这个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的创建独立一个函数出来
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
viewModel.onMessageError.observe(this, onMessageErrorObserver)
viewModel.isEmptyList.observe(this, emptyListObserver)
__}**
observers观察者部分
有变化就改变view层,并且通知适配器更新
private val renderMuseums = Observer> {
Log.v(TAG, “data updated $it“)
layoutError.visibility = View.GONE
layoutEmpty.visibility = View.GONE
adapter.update(it)
**}
private val isViewLoadingObserver = Observer
Log.v(TAG, “isViewLoading $it“)
val visibility = if (it) View.VISIBLE else View.GONE
progressBar.visibility = visibility
}
private val onMessageErrorObserver = Observer
Log.v(TAG, “onMessageError $it“)
layoutError.visibility = View.VISIBLE
layoutEmpty.visibility = View.GONE
textViewError.text = “Error $it“
}
private val emptyListObserver = Observer
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>().apply { value = emptyList() }
val museums: LiveData> = _museums
private val _isViewLoading = MutableLiveData
val isViewLoading: LiveData
private val _onMessageError = MutableLiveData
val onMessageError: LiveData
private val isEmptyList = MutableLiveData
val isEmptyList: LiveData
�
如果你需要这些数据只被加载一次,可以考虑init中调用loadMuseums()。这个时候,如果你旋转屏幕,这个方法不会被调用
init {
//loadMuseums()
}
/
fun loadMuseums() {
_isViewLoading.value = true
//repository是由构造函数传入的,fetchMuseum是其下的一个方法
/*
_fun fetchMuseums(callback: OperationCallback
museumDataSource.retrieveMuseums(callback)
}
museumDataSoruce是一个接口,内部有fetchMuseums方法,传入一个callback
*/
repository.fetchMuseums(object : OperationCallback
override fun onError(error: String?) {
_isViewLoading.value = false
_onMessageError.value = error
}
**override fun **onSuccess(data: List<Museum>?) {<br /> _isViewLoading.value = **false<br /> if **(data.isNullOrEmpty()) {<br /> _isEmptyList.value = **true
**} **else **{<br /> _museums.value = data<br /> }<br /> }<br /> })<br />}<br />��<br />�