我正在用diff util实现一个回收器视图,但是当我第一次把列表发送到适配器时,回收器视图没有收到新列表的通知。只有当我第二次更新列表时,回收器才收到通知。我尝试了几种解决类似问题的方法,但是都不起作用。如果有人能帮忙,先谢谢。
下面是我的代码:
适配器:
class UserListAdapter : Adapter<UserListItemViewHolder>() {
private var mUsers = mutableListOf<User>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserListItemViewHolder =
UserListItemViewHolder.create(parent)
override fun onBindViewHolder(holder: UserListItemViewHolder, position: Int) {
holder.bind(mUsers[position])
}
override fun getItemCount(): Int = mUsers.size
fun updateUsersList(users: List<User>) {
val diffCallback = UserListDiffCallback(this.mUsers, users)
val diffResult = DiffUtil.calculateDiff(diffCallback)
this.mUsers.clear()
this.mUsers.addAll(users)
diffResult.dispatchUpdatesTo(this)
}
}
用户列表差异回调:
class UserListDiffCallback(
private val oldList: List<User>,
private val newList: List<User>
) : DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition].username == newList[newItemPosition].username
}
override fun getOldListSize(): Int {
return oldList.size
}
override fun getNewListSize(): Int {
return newList.size
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return true
}
}
视图模型:
@HiltViewModel
class MainViewModel @Inject constructor(
private val getUsersUseCase: GetUsersUseCase
) : ViewModel() {
private val _usersResultStatus = MutableLiveData<ResultStatus>(NotLoading)
val usersResultStatus: LiveData<ResultStatus>
get() = _usersResultStatus
private val _users = MutableLiveData<MutableList<User>?>()
val users: LiveData<MutableList<User>?>
get() = _users
fun getUsers() {
viewModelScope.launch {
try {
_usersResultStatus.value = Loading
_users.value = getUsersUseCase()
} catch (error: Throwable) {
_usersResultStatus.value = Error(error)
} finally {
_usersResultStatus.value = NotLoading
}
}
}
}
在活动中更新列表的位置:
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private var _binding: ActivityMainBinding? = null
private val binding: ActivityMainBinding get() = _binding!!
private val viewModel: MainViewModel by viewModels()
private val usersAdapter = UserListAdapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initUsersAdapter()
observeStates()
viewModel.getUsers()
}
private fun initUsersAdapter() {
with(binding.recyclerView) {
setHasFixedSize(true)
adapter = usersAdapter
}
}
private fun observeStates() {
viewModel.usersResultStatus.observe(this) { resultStatus ->
setProgressbarVisibility(resultStatus is Loading)
if (resultStatus is Error) {
Toast.makeText(
this@MainActivity,
getString(R.string.error),
Toast.LENGTH_SHORT
).show()
}
}
viewModel.users.observe(this) { users ->
users?.let {
usersAdapter.updateUsersList(users.toMutableList())
}
}
}
private fun setProgressbarVisibility(show: Boolean) {
binding.progressBar.visibility = if (show) View.VISIBLE else View.GONE
}
}
1条答案
按热度按时间nnvyjq4y1#
尝试添加项目范围更改到您的代码对我来说是这样的