更改 LiveData 数据后不会更新 UI

时间:2021-03-21 03:31:51

标签: android android-livedata android-jetpack

这是我的代码:

class HomeFragment : Fragment() {
    val viewModel by lazy {
        ViewModelProvider(this)[HomeViewModel::class.java]
    }

    private lateinit var adapter: ArticleListAdapter

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val root = inflater.inflate(R.layout.fragment_home, container, false)
        return root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        val linearLayoutManager = LinearLayoutManager(activity)
        rv_home.layoutManager = linearLayoutManager
        adapter = ArticleListAdapter(viewModel.articleList)
        rv_home.adapter = adapter
        viewModel.getHomeArticle(0)


        viewModel.articleLiveData.observe(viewLifecycleOwner, { result ->
            val HomePages = result.getOrNull()
            viewModel.articleList = HomePages
            adapter.notifyDataSetChanged()
        })
    }

}
class HomeViewModel : ViewModel() {
    var articleList: HomeArticleBean? = null
    private val observerArticleLiveData = MutableLiveData<Int>()
    val articleLiveData = Transformations.switchMap(observerArticleLiveData) { page ->
        Repository.getHomeArticles(page)
    }

    fun getHomeArticle(page: Int) {
        observerArticleLiveData.value = page
    }
}

当我从 HomeFragment 调用 getHomeArticle() 时,程序应该执行

Repository.getHomeArticles(page)

但是在Dubug之后我发现这行代码不会被执行。 这导致我在 HomeFragment 中的文章 LiveData 观察无效,从而阻止我更新 UI。我是 Jetpack 的新手,所以我不知道为什么会发生这种情况,我的代码是在别人的代码之后编写的,我运行他的代码没有问题,我仔细查看了我的代码和他的代码之间是否存在差异,但没有没有找到。我在网上找了很久。但是没有用。请帮助或尝试提供一些关于如何实现这一目标的想法。提前致谢。

1 个答案:

答案 0 :(得分:0)

您的问题在于您对 viewModel.articleList 的使用:

   adapter = ArticleListAdapter(viewModel.articleList)

这会创建您的适配器并将其数据与当前存储在 viewModel.articleList 的列表相关联(出于某种原因,它不在您的 HomeViewModel 代码中?)

   viewModel.articleList = HomePages

这一行完全丢弃了当前存储在 viewModel.articleList 的列表,并重新分配变量以存储一个全新的列表。您的适配器对这个新列表一无所知 - 它仍然引用旧列表。

因此,您有几个选择:

  1. 让您的 ArticleListAdapter 有一个采用新列表的 setData 方法。 setData 将更新 ArcticleListAdapter 正在跟踪的列表(并且,作为一个好处,它也可以在内部调用 notifyDataSetChanged(),使其始终被调用。

  2. 用新条目更新 viewModel.articleList,而不是替换整个列表,从而确保 ArticleListAdapter 使用的列表具有您更新的数据:

viewModel.articleLiveData.observe(viewLifecycleOwner, { result ->
    val HomePages = result.getOrNull()
    viewModel.articleList.clear()
    if (HomePages != null) {
        viewModel.articleList.addAll(HomePages)
    }
    adapter.notifyDataSetChanged()
})
  1. 使您的 ArticleListAdapter 扩展 ListAdapter。此类为您处理跟踪数据列表,并为您提供一个简单的 submitList 方法,您可以从 observe 方法调用该方法。作为附带的好处,它使用了 DiffUtil,这方式notifyDataSetChanged() 更有效。