这几天在学习DataBinding,ViewMode, MVVM, LiveData,,, 比照Sunflower项目, 重新了自己的项目.
我的项目截图:
简单来说是一个列表, recycleView实现的, 当滑到底部后加载更多数据, 拼接在最后.
用了ViewModel加载更多数据, 这也是MVVM中要求的. 类名: FollowTopicListViewModel
实际的列表数据是保存在在ViewModel中的LiveData变量中的
val topicList = MutableLiveData<List<Express>>()
但是当加载更多数据并设置到topicList 后, 页面上的RecyclerView并没有显示出新加载的数据.
具体的使用代码:
viewModel.topicList.observe(this, Observer { topics ->
....
adapter.submitList(topics)
....
})
这里想说的是submitList不能刷新数据的问题, 所以这里省略了一些其他代码. 基本来说就是这么使用的, 当viewModel中的LiveData变量topicList发生变化时, 会触发 adapter.submitList(topics)
按照它的示例, 以为这么做没问题, 但是谁知道就是不刷新, 当然我也可以在submitList之后调用adapter.notifyDataSetChanged()手工更新数据. 但是谷歌既然提供submitList必然不会是想让你手工notify的.
费解啊! 无奈啊! 折腾了半天, 才弄明白, 原来这里的参数topics的赋值有要求:
ListAdapter.java: submitList() --> AsyncListDiffer.java :submitList()
public void submitList(@Nullable final List<T> newList) {
if (newList == mList) {
// nothing to do
return;
}
......
如果传入的列表跟之前的列表是同一个对象, 那么就什么都不会更新, 直接返回了. (WTF!!)
所以解决办法就是在加载更多数据之后, 新生成一个新的全量list, 赋值给topicList
......
var newList:MutableList<Express> = mutableListOf()
newList.addAll(expressList)
topicList.postValue(newList)
.....
这么做就OK了, 但是感觉效率很低啊, stackoverflow上还有人说可以这么做:
topicList.postValue(null)
topicList.postValue(newList)
就是先设置一个null值, 再设置你想要设置的列表值, 这也能解决, 但是这感觉更扯淡
谁有更好的办法?
麻烦告诉我, 谢谢!
最终的代码在:
https://github.com/shaopx/LiteDig -- 首页-> 关注 这个列表是使用的mvvm方式开发的