【问题标题】:Android Jetpack: RecyclerView is not updating when LiveData is setAndroid Jetpack:设置 LiveData 时 RecyclerView 未更新
【发布时间】:2018-06-10 00:52:59
【问题描述】:

所以我有一个简单的实现来在RecyclerView 中显示用户列表,并在ViewModel 中以LiveData 查询该列表。

问题在于 UI 没有更新以显示最新列表 - 称为 users - 即使在观察到列表时也是如此。我现在只是设置了一个演示用户列表。

这是我的 ViewModel:

class MainViewModel : ViewModel() {

    private val demoData = listOf(
            User(userName = "Bob", favoriteColor = "Green"),
            User(userName = "Jim", favoriteColor = "Red"),
            User(userName = "Park", favoriteColor = "Blue"),
            User(userName = "Tom", favoriteColor = "Yellow"),
            User(userName = "Lee", favoriteColor = "Black"),
            User(userName = "Xiu", favoriteColor = "Gray")
    )

    private val _users = MutableLiveData<List<User>>()
    val users: LiveData<List<User>>
        get() = _users

    init {
        _users.value = listOf()
    }

    fun loadUsers() {
        _users.value = demoData.toMutableList().apply { shuffle() }
    }
}

还有我的 ViewModel 的附加片段:

// ...

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)

    viewModel.users.observe(this, Observer {
        mAdapter.notifyDataSetChanged()
    })

    mAdapter = UsersAdapter(viewModel.users.value!!)

    mainRV = view?.findViewById<RecyclerView>(R.id.rv_main)?.apply {
        adapter = mAdapter
        layoutManager = LinearLayoutManager(view?.context)
    }

    viewModel.loadUsers()
}

附: UsersAdapter 是通常的RecyclerView.Adapter

我已经确保在我的用户列表中调用setValue 来调用观察者,因此我不确定这里缺少什么。我的适配器是否设置错误?

【问题讨论】:

  • 这将有助于至少查看适配器的“绑定”部分。另外你不需要调用apply{},你可以直接调用shuffle()。通常新列表在观察者回调中传递给适配器。
  • 因为列表没有就地变异。你getValue 第一个值就是这样。您应该将 observe 方法中的新列表设置为您的适配器。

标签: android android-recyclerview kotlin android-jetpack android-livedata


【解决方案1】:
fun loadUsers() {
    _users.value = demoData.toMutableList().apply { shuffle() }
}

toMutableList() 用数据创建一个新列表,见源代码:

public fun <T> Collection<T>.toMutableList(): MutableList<T> {
    return ArrayList(this)
}

因此,您应该更新适配器中的列表并显示它,而不是获取初始值并且从不更新适配器。

viewModel.users.observe(this, Observer { users ->
    mAdapter.updateData(users)
})

如果你不是using ListAdapter,那么你可以这样定义这个方法:

class MyAdapter: RecyclerView.Adapter<ViewHolder>(
   private var list: List<User> = Collections.emptyList()
) {
    ...

    fun updateData(users: List<User>) {
        this.users = users
        notifyDataSetChanged()
    }
}

你也可以使用ListAdapter and submitList,你也会得到动画。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    相关资源
    最近更新 更多