【问题标题】:RecyclerView gets not notified about visual changes when using the recyclerview-selection library使用 recyclerview-selection 库时,RecyclerView 不会收到有关视觉更改的通知
【发布时间】:2021-01-27 12:49:49
【问题描述】:

我已经成功实现了recyclerview-selection 库。现在我正在尝试使用SelectionTracker.setItemsSelected(keys: Iterable<K>, selected: boolean) 方法制作一个“选择所有项目”按钮。到现在为止还挺好。我现在的问题是一些看不见的物品没有得到目视检查。但是,如果我在按下按钮之前向下滚动到列表末尾,就会发生这种情况。在后台检查所有项目,我可以在应用栏的文本中看到这些项目。

示例:我滚动到列表末尾并备份,然后按“选择所有项目”按钮。正如您在图片中看到的,有些项目在视觉上没有被检查。

如果我按下后退按钮来删除所有项目的选中状态,也会发生类似的事情。


现在我的问题是:recyclerview 库中是否存在导致这种奇怪的 gui 行为的错误,或者我做错了什么?我正在使用以下版本:recyclerview-selection:1.1.0-rc03


编辑:

这里是我的 RecyclerView.ViewHolder 类的绑定方法:

fun bind(event: Event, selected: Boolean) {
    val imgSize = if (selected) SELECTION_IMG_EXTENDED_SIZE else SELECTION_IMG_REDUCED_SIZE
    animateResize(imgSize, ...)
}

【问题讨论】:

    标签: android kotlin android-recyclerview notifydatasetchanged


    【解决方案1】:

    根据documentation,我通过覆盖以下方法解决了这个问题:

    RecyclerView.Adapter:

    override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
          val isSelected = selectionTracker.isSelected(holder.itemId)
          holder.setItemSelected(isSelected)
    }
    

    我不知道这是否是解决问题的推荐方法,但也许它会对某人有所帮助。如果您有任何其他提示或信息,请告诉我!


    编辑:

    这里是完整的代码:

    class EventAdapterAll(private val context: Context) : ListAdapter<Event, EventAdapterAll.EventViewHolder>(EventAdapterDiffCallback()) {
    
        private val commonListAdapter = CommonListAdapter()
    
        init {
            setHasStableIds(true)
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EventViewHolder {
            val binding = LayoutEventItemAllBinding.inflate(LayoutInflater.from(parent.context), parent, false)
            return EventViewHolder(binding)
        }
    
       override fun onBindViewHolder(holder: EventViewHolder, position: Int) {
            val currentItem = getItem(position)
            commonListAdapter.selectionTracker?.let {
               holder.bind(currentItem, it.isSelected(getItemId(position)))
            }
        }
    
        override fun onViewAttachedToWindow(holder: EventViewHolder) {
            val isSelected = commonListAdapter.selectionTracker?.isSelected(holder.itemId)
            if (isSelected != null) {
                holder.setItemSelected(isSelected)
            }
        }
    
        //...
    
        inner class EventViewHolder(private val binding: LayoutEventItemAllBinding) : RecyclerView.ViewHolder(binding.root) {
    
            fun bind(event: Event, selected: Boolean) = with(binding) {
                setItemSelected(selected)
                //...
            }
    
            fun setItemSelected(selected: Boolean) {
                val imgSize = if (selected) SELECTION_IMG_EXTENDED_SIZE else SELECTION_IMG_REDUCED_SIZE
                commonListAdapter.animateResize(binding.imgEventSelection, imgSize, context)
            }
        }
    }
    

    当向下/向上滚动并且列表项变得可见时,onViewAttachedToWindow 确保列表中的选择状态得到更新。

    【讨论】:

    • 我不推荐这种方法,你可以在 bind 作为适配器的一部分这样做,基本上就像我们在这里做的那样:github.com/ExpensiveBelly/RecyclerViewSelection/blob/master/app/…
    • 感谢您的评论!我在问题中添加了我的“绑定”方法的一部分。当然,我根据“绑定”方法中的选择模式切换视图状态。为了解决所描述的问题,我还必须重写 'onViewAttachedToWindow' 方法。
    • 这实质上会导致每个视图在可见时被反弹。如果用户快速滚动,可能会导致性能问题。它确实解决了这个问题。 @Tobi 不清楚您的链接如何解决问题。如果你能写一个答案并解释这部分的内容会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 2021-05-29
    相关资源
    最近更新 更多