如何解决如何禁用更新项目时发生的 RecyclerView (ListAdapter) 的自动滚动?
背景
我有一个用户界面,显示用户全名列表,每个项目都有一个喜欢/不喜欢按钮。我正在使用一个 listadapter
,它在底层使用 DiffUtil
和 AsyncListDiffer
API。用户列表作为来自 Room 数据库的 LiveData 接收,并按“isLiked”排序。
问题
每当点击“赞”按钮时,我使用 LiveData 时的 Room 都会将新数据重新提交给适配器。问题是,由于列表是按“isLiked”排序的,喜欢的用户会改变它的位置,而 RecyclerView 将始终滚动到新位置。
我不想看到更新项的新位置。那么,如何禁用自动滚动行为?
我尝试了什么
MainActivity.kt
..
val userAdapter = UsersAdapter(this)
val ll = linearlayoutmanager(this,linearlayoutmanager.VERTICAL,false)
recyclerView.apply {
layoutManager = ll
adapter = userAdapter
itemAnimator = null
setHasFixedSize(true)
}
viewmodel.users.observe(this,{
// This will force the recycler view to scroll back to the prevIoUs position
// But it's more of a workaround than a clean solution.
val pos = ll.findFirstVisibleItemPosition()
userAdapter.submitList(it) {
recyclerView.scrollToPosition(pos)
}
})
..
UsersAdapter.kt
class UsersAdapter(
private val clickListener: UserClickListener
) : listadapter<UserEntity,UsersAdapter.UserViewHolder>(DIFF_CALLBACK) {
override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): UserViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_user,parent,false)
return UserViewHolder(view)
}
override fun onBindViewHolder(holder: UserViewHolder,position: Int) {
val userEntity = getItem(position)
holder.bind(userEntity,clickListener)
}
class UserViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val textView: TextView = view.findViewById(R.id.fullName)
private val fav: ImageButton = view.findViewById(R.id.fav)
fun bind(user: UserEntity,clickListener: UserClickListener) {
textView.text = user.fullName
val favResId = if (user.favorite) R.drawable.like else R.drawable.dislike
fav.setimageResource(favResId)
fav.setonClickListener {
val newFav = !user.favorite
val newFavResId = if (newFav) R.drawable.like else R.drawable.dislike
fav.setimageResource(newFavResId)
clickListener.onUserClicked(user,newFav)
}
}
}
interface UserClickListener {
fun onUserClicked(user: UserEntity,isFavorite: Boolean)
}
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<UserEntity>() {
override fun areItemsTheSame(
oldUser: UserEntity,newUser: UserEntity
) = oldUser.id == newUser.id
override fun areContentsTheSame(
oldUser: UserEntity,newUser: UserEntity
) = oldUser.fullName == newUser.fullName && oldUser.favorite == newUser.favorite
}
}
}
我尝试使用常规 RecyclerView 适配器和 DiffUtil,并将检测移动设置为 false。
我也添加了 AsyncListDiffer。
我尝试了 listadapter,甚至尝试了分页库并使用了 Pagedlistadapter。
DiffUtil 的回调更改了自动滚动,但我无法获得所需的行为。
非常感谢任何帮助!
解决方法
发生这种情况是因为您正在更新 VH 状态,也许您可以在“提交列表”调用之前删除用户喜欢的 VH。
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
viewModel.users.observe(this,{ userAdapter.submitList(it) }
}
...
override fun onViewHolderClick(model: UserEntity) {
userAdapter.removeItem(model)
viewModel.updateItem(model)
}
并在您的适配器中添加此功能
UsersAdapter.kt
...
fun removeItem(model: UserEntity) {
val currentListCopy = mutableListOf<UserEntity>().apply { addAll(currentList) }
currentListCopy.remove(model)
submitList(currentListCopy)
}
...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。