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

View

页面需要的变量
private val viewModel by viewModels {
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的创建独立一个函数出来
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.isViewLoading.observe(this, isViewLoadingObserver)
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 = _isViewLoading

private val _onMessageError = MutableLiveData()
val onMessageError: LiveData = _onMessageError

private val isEmptyList = MutableLiveData()
val isEmptyList: LiveData = _isEmptyList

/
如果你需要这些数据只被加载一次,可以考虑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
}

  1. **override fun **onSuccess(data: List<Museum>?) {<br /> _isViewLoading.value = **false<br /> if **(data.isNullOrEmpty()) {<br /> _isEmptyList.value = **true
  2. **} **else **{<br /> _museums.value = data<br /> }<br /> }<br /> })<br />}<br />��<br />�