android - 带有 LayoutBinding 的 RecyclerView - 滑动以删除 - 留下项目大小的空白空间
问题描述
我在网上搜索了很多,但显然无法找到答案。我有一个待办事项列表,并且适配器附加了滑动功能,因此当有人滑动项目时,它会从列表中删除该项目。
问题是被删除的项目被新项目替换,但该区域显示为空白区域。
我知道那里有行项目但没有显示,如果我关闭应用程序并再次打开它会显示。
这是我的适配器类。
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
class TodoAdapter(var allTodos: ArrayList<Todo>, var callback: iTodoAdapter)
: RecyclerView.Adapter<TodoAdapter.TodoViewHolder>(),
ItemTouchHelperCustomListener {
//Hello
override fun onItemDismiss(position: Int) {
callback.onDelete(position)
}
override fun onItemMove(fromPosition: Int, toPosition: Int) : Boolean {
callback.onItemsSwapped(fromPosition, toPosition)
return true
}
override fun updateDatabasePositions(fromPosition: Int, toPosition: Int) {
val size = allTodos.size - 1
for (index in 0..size) {
allTodos.get(index).position = index
}
callback.onPositionsUpdated()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : TodoViewHolder {
val binding = LayoutTodoItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return TodoViewHolder(binding)
}
override fun getItemCount(): Int {
return allTodos.size
}
private fun createOnClickListener(position: Int) : View.OnClickListener {
return View.OnClickListener {
val checked = (it as CheckBox).isChecked
allTodos.get(position).isSelected = checked
allTodos.get(position).let { callback.onItemUpdated(it) }
}
}
override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
holder.bind(allTodos.get(position), createOnClickListener(position))
}
//We only have 1 type of item
override fun getItemViewType(position: Int): Int {
return position
}
class TodoViewHolder(private val binding : LayoutTodoItemBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(todoItem : Todo?, clickListner: View.OnClickListener) {
binding.apply {
setTodoItem(todoItem)
onClickListener = clickListner
executePendingBindings()
}
}
}
fun getData() : ArrayList<Todo> {
return this.allTodos
}
interface iTodoAdapter {
fun onDelete(position: Int)
fun onItemsSwapped(from: Int, to: Int)
fun onPositionsUpdated()
fun onItemUpdated(item: Todo)
}
}
这是我的片段中实现的 iTodoAdapter
override fun onDelete(position: Int) {
viewModel.delete(allTodos.get(position))
}
override fun onItemsSwapped(from: Int, to: Int) {
Collections.swap(allTodos, from, to)
rcyTodo?.adapter?.notifyDataSetChanged()
}
override fun onPositionsUpdated() {
viewModel.updateAll((rcyTodo?.adapter as TodoAdapter).getData())
}
override fun onItemUpdated(item: Todo) {
viewModel.update(item)
}
这是我的片段设置:
val dividerItemDecoration = DividerItemDecoration(rcyTodo.context,DividerItemDecoration.VERTICAL)
rcyTodo.addItemDecoration(dividerItemDecoration)
rcyTodo.apply {
adapter = TodoAdapter(allTodos, this@Todo)
setHasFixedSize(true)
}
setupSwipeToDelete()
setCurrentItems()
这里是函数
private fun setupSwipeToDelete() {
val itemTouchHelperCallback = ItemTouchHelperCallback(rcyTodo.adapter as TodoAdapter)
val itemTouchHelper = ItemTouchHelper(itemTouchHelperCallback)
itemTouchHelper.attachToRecyclerView(rcyTodo)
}
@SuppressLint("CheckResult")
private fun setCurrentItems() {
viewModel.getAllTodos().subscribe({
allTodos.clear()
allTodos.addAll(it)
rcyTodo?.recycledViewPool?.clear()
rcyTodo?.adapter?.notifyDataSetChanged()
}, {
})
}
我在某处发现清理池 (rcyTodo?.recycledViewPool?.clear()) 应该重绘项目但不起作用。
我在想我是否必须删除布局绑定并以简单的方式进行?有办法解决吗?我错过了什么吗?顺便说一句,空白空间确实有项目,这只发生在我滑动后删除一个项目时。与绘图元素有关,不知何故回收者视图认为这个位置应该是空的。
解决方案
使用您的notifyDataSetChanged
,在适配器上再调用一个功能 - notifyItemRemoved(position)
。文档说:
通知任何已注册的观察者,先前位于该位置的项目已从数据集中删除。现在可以在 oldPosition - 1 找到以前位于 position 和之后的项目。
希望它成功:-)
推荐阅读
- apache - Apache Proxy 没有从 Jenkins、Nexus、Sonarqube 的正确路径中提取资源
- android - kotlin 中的 setLayoutManager
- python - 如何使用 Spark 将文件保存到 Parquet,以便在读取期间标头准备好/可用?
- python - 使用 CMD 命令的可执行 python 脚本不起作用
- c# - 我对 Unity 瓷砖托盘有疑问,有人可以帮我吗?
- java - 无法访问 Java 库
- php - 迁移到云端后,sql查询超时
- javascript - 用于进行 API 调用的 JS 函数
- html - 在 css 中使用变量设置字体系列会导致滚动问题
- javascript - 必须指定一个渲染道具,一个渲染函数作为子级,或者一个组件道具到 Field(auto)