kotlin DiffUtil(dispatchUpdatesTo)未更新回收器视图

9gm1akwq  于 2023-02-19  发布在  Kotlin
关注(0)|答案(1)|浏览(193)

我正在用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
    }
}
nnvyjq4y

nnvyjq4y1#

尝试添加项目范围更改到您的代码对我来说是这样的

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)
        notifyItemRangeChanged(0, users.size)
 
    }

相关问题