以编程方式向 RecyclerView 项目添加一些视图会创建一个已知错误
Adding Some View to RecyclerView item programmatically creates an known bug
所以我正在创建一个待办事项应用程序,用户可以在其中设置优先级,优先级星号是通过绑定适配器以编程方式添加的,但是当滚动任务回收器视图时,星号为零的任务也显示星号,其中检查日志显示为零星星。此外,仅当我滚动到带星标的项目然后开始严格滚动时才会出现此错误
- 应用刚刚启动
- 已滚动到带有任务星标的项目
- 严格滚动后
我已尝试在每次更新项目时创建新的 ArrayList
片段代码:
viewModel.taskCategory.observe(viewLifecycleOwner, Observer { taskCategoryPair ->
taskCategoryPair?.let {
Log.i("HomeFragment","Submitting New List")
viewModel.filterDataFinish()
adaptor.submitList(it)
}
})
RecyclerView 绑定代码:
RecyclerView.ViewHolder(binding.root) {
fun bind(
task: ToDo,
category: Category,
clickListener: MiscellaneousUtils.GetIdFromClick
) {
binding.task = task
binding.category = category
binding.clickListener = clickListener
binding.onCheckChangeListener = categorizedTasksClickListeners
binding.root.setOnLongClickListener {
categorizedTasksClickListeners.onLongClickItem(adapterPosition,it)
true
}
binding.executePendingBindings()
}
添加星星的BindingAdapter函数:
@BindingAdapter("app:setPriority")
fun LinearLayoutCompat.setPriority(task: ToDo) {
if (task.priorityStars == 0)
return
val previousStarContainer = findViewWithTag<LinearLayout>("starContainerLayout")
if (previousStarContainer != null) {
removeView(previousStarContainer)
}
val starContainer = LinearLayout(context)
starContainer.tag = "starContainerLayout"
starContainer.layoutParams = LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
for (count in 1..task.priorityStars) {
val starView = ImageView(context)
starView.setImageResource(R.drawable.task_star)
starView.layoutParams = LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
starContainer.addView(starView)
}
addView(starContainer)
}
Recycler 回收视图 :) - 它使用相同的视图来显示多个数据!这意味着视图可用于显示带有星星的对象 - 所以在 onBindViewHolder
上显示星星。然后相同的视图(现在有星星)将用于显示不同的对象(没有星星对象)——这意味着在 onBindViewHolder
上你现在需要隐藏星星,我敢打赌你没有; )
正如我所说,如果你没有星星,你就不会删除之前的开始:
if (task.priorityStars == 0)
return
将您的代码更改为:
@BindingAdapter("app:setPriority")
fun LinearLayoutCompat.setPriority(task: ToDo) {
val previousStarContainer = findViewWithTag<LinearLayout>("starContainerLayout")
if (previousStarContainer != null) {
removeView(previousStarContainer)
}
if (task.priorityStars == 0)
return
val starContainer = LinearLayout(context)
starContainer.tag = "starContainerLayout"
starContainer.layoutParams = LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
for (count in 1..task.priorityStars) {
val starView = ImageView(context)
starView.setImageResource(R.drawable.task_star)
starView.layoutParams = LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
starContainer.addView(starView)
}
addView(starContainer)
}
所以我正在创建一个待办事项应用程序,用户可以在其中设置优先级,优先级星号是通过绑定适配器以编程方式添加的,但是当滚动任务回收器视图时,星号为零的任务也显示星号,其中检查日志显示为零星星。此外,仅当我滚动到带星标的项目然后开始严格滚动时才会出现此错误
- 应用刚刚启动
- 已滚动到带有任务星标的项目
- 严格滚动后
我已尝试在每次更新项目时创建新的 ArrayList
片段代码:
viewModel.taskCategory.observe(viewLifecycleOwner, Observer { taskCategoryPair ->
taskCategoryPair?.let {
Log.i("HomeFragment","Submitting New List")
viewModel.filterDataFinish()
adaptor.submitList(it)
}
})
RecyclerView 绑定代码:
RecyclerView.ViewHolder(binding.root) {
fun bind(
task: ToDo,
category: Category,
clickListener: MiscellaneousUtils.GetIdFromClick
) {
binding.task = task
binding.category = category
binding.clickListener = clickListener
binding.onCheckChangeListener = categorizedTasksClickListeners
binding.root.setOnLongClickListener {
categorizedTasksClickListeners.onLongClickItem(adapterPosition,it)
true
}
binding.executePendingBindings()
}
添加星星的BindingAdapter函数:
@BindingAdapter("app:setPriority")
fun LinearLayoutCompat.setPriority(task: ToDo) {
if (task.priorityStars == 0)
return
val previousStarContainer = findViewWithTag<LinearLayout>("starContainerLayout")
if (previousStarContainer != null) {
removeView(previousStarContainer)
}
val starContainer = LinearLayout(context)
starContainer.tag = "starContainerLayout"
starContainer.layoutParams = LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
for (count in 1..task.priorityStars) {
val starView = ImageView(context)
starView.setImageResource(R.drawable.task_star)
starView.layoutParams = LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
starContainer.addView(starView)
}
addView(starContainer)
}
Recycler 回收视图 :) - 它使用相同的视图来显示多个数据!这意味着视图可用于显示带有星星的对象 - 所以在 onBindViewHolder
上显示星星。然后相同的视图(现在有星星)将用于显示不同的对象(没有星星对象)——这意味着在 onBindViewHolder
上你现在需要隐藏星星,我敢打赌你没有; )
正如我所说,如果你没有星星,你就不会删除之前的开始:
if (task.priorityStars == 0)
return
将您的代码更改为:
@BindingAdapter("app:setPriority")
fun LinearLayoutCompat.setPriority(task: ToDo) {
val previousStarContainer = findViewWithTag<LinearLayout>("starContainerLayout")
if (previousStarContainer != null) {
removeView(previousStarContainer)
}
if (task.priorityStars == 0)
return
val starContainer = LinearLayout(context)
starContainer.tag = "starContainerLayout"
starContainer.layoutParams = LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
for (count in 1..task.priorityStars) {
val starView = ImageView(context)
starView.setImageResource(R.drawable.task_star)
starView.layoutParams = LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
starContainer.addView(starView)
}
addView(starContainer)
}