简体   繁体   English

在notifyItemRangeInserted之后未调用RecyclerView onCreateViewHolder

[英]RecyclerView onCreateViewHolder not called after notifyItemRangeInserted

Here is my recyclerView init: 这是我的recyclerView初始化:

messageList = findViewById(R.id.fragmentMessenger_list)
val layoutManager = LinearLayoutManager(activity)
layoutManager.stackFromEnd = true
messageList.layoutManager = layoutManager
messageList.adapter = messengerAdapter

all works fine here. 在这里一切正常。

when I receive new data list, I am trying to update recyclerViewAdapter with help of diffUtil: 当我收到新的数据列表时,我正在尝试借助diffUtil更新recyclerViewAdapter

fun swap(list: ArrayList<QMessage>){       
    val diffUtilCallback = ListDiffUtilCallback(itemsList, list)
    val diffResult = DiffUtil.calculateDiff(diffUtilCallback)

    itemsList.clear()
    itemsList.addAll(list)
    diffResult.dispatchUpdatesTo(this@MessengerAdapter)
}

I know that it recomended to use in separate thread, but just for example diffUtill work in ui thread 我知道建议在单独的线程中使用它,但是例如diffUtill在ui线程中工作

So each time when there are some data updates, I receive a new list of all messages. 因此,每次进行一些数据更新时,我都会收到所有消息的新列表。

The problem is that when I already have few messages (for example two), and they are bigger than one screen (we need to swipe to see them full) and receive 3rd one - adapter doesn't scroll to bottom. 问题是 ,当我已经收到很少的消息(例如两条消息)并且它们大于一个屏幕时(我们需要滑动才能看到完整的消息)并收到第三个消息-适配器不会滚动到底部。 but if even I do it manually, there is no 3rd message! 但是,即使我手动执行此操作,也不会收到第三条消息! Until I make some swipe up and then down again! 直到我向上滑动然后再次向下滑动!

Is anybody familiar with this kind of? 有人熟悉这种吗?

Any ideas why it's happening and how to fix? 有什么想法为什么会发生以及如何解决?

UPDATE: by the way, the same behavior with next swapping data: 更新:顺便说一下,下一次交换数据的行为相同:

val position = itemsList.size +1
itemsList.addAll(newItems)
notifyItemRangeInserted(position, newItems.size)

UPDATE 2: just figured with the logs that after insert getItemCount return correct list size (so this method was called), but onCreateViewHolder was not called after insert! 更新2:只是想知道在插入getItemCount返回正确的列表大小的日志(因此调用了此方法),但是在插入之后未调用onCreateViewHolder

UPDATE 3: here is my adapter: class MyAdapter(): RecyclerView.Adapter() { 更新3:这是我的适配器:类MyAdapter():RecyclerView.Adapter(){

    interface MessageClickListener{
    }

    private var listener:MessageClickListener? = null
    private lateinit var layoutManager: LinearLayoutManager
    private var itemsList = ArrayList<QMessage>()
    private var itemsListSize = 0

    override fun getItemCount(): Int {
        itemsListSize = itemsList.size
        L.log("getItemCount $itemsListSize")
        return itemsListSize
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
        L.log("onBindViewHolder position = $position")
        val message = itemsList[position]
        if (holder is MessageType1) {
            L.log("onBindViewHolder MessageType1")
            holder.bind(message, listener)
        } else if (holder is MessageType2) {
            L.log("onBindViewHolder MessageType2")
            holder.bind(message, listener)
        } else if (holder is MessageType3) {
            L.log("onBindViewHolder MessageType3")
            holder.bind(message, listener)
        } else {
            L.log("onBindViewHolder unknown")
        }
    }

    override fun getItemViewType(position: Int): Int {
        val item = itemsList[position]
        return item.type.toInt()
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder? {
        return when(viewType){
            QMessageType.MESSAGE_TYPE_1.toInt() -> {
                L.log("onCreateViewHolder MESSAGE_TYPE_1")
                MessageType1(parent!!)
            }
            QMessageType.MESSAGE_TYPE_2.toInt() -> {
                L.log("onCreateViewHolder MESSAGE_TYPE_2")
                MessageType2(parent!!)
            }
            QMessageType.MESSAGE_TYPE_3.toInt() -> {
                L.log("onCreateViewHolder MESSAGE_TYPE_3")
                MessageType3(parent!!)
            }
            else -> {
                L.log("onCreateViewHolder default")
                return MessageType1(parent!!)
            }
        }
    }

    fun setup(l:MessageClickListener, lm: LinearLayoutManager){
        if (listener != null)
            return
        listener = l
        this.layoutManager = lm
    }


    fun swap(list: ArrayList<QMessage>){
        L.log("swap called. listSize = ${list.size}")
        if (list.isEmpty())
            return

        val newItems = list.minus(itemsList)
        L.log("newItems = ${newItems.size}")

        val position = itemsList.size +1
        itemsList.addAll(newItems)
        notifyItemRangeInserted(position, newItems.size)
    }

}

UPDATE 4: logs: 更新4:日志:

D: getItemCount 0
D: getItemCount 0
D: swap called. listSize = 0
D: swap called. listSize = 2
D: newItems = 2
D: getItemCount 2
D: getItemCount 2
D: onCreateViewHolder MESSAGE_TYPE_2
D: onBindViewHolder position = 1
D: onBindViewHolder MessageType2
D: getItemCount 2
D: onCreateViewHolder MESSAGE_TYPE_1
D: onBindViewHolder position = 0
D: onBindViewHolder MessageType1
D: getItemCount 2
D: getItemCount 2
D: swap called. listSize = 3
D: newItems = 1
D: getItemCount 3
D: getItemCount 3

as we can see, after second swap there was no onCreateViewHolder call 如我们所见,第二次交换后没有onCreateViewHolder调用

Just return itemsList.size is enough 只需返回itemsList.size就足够了

override fun getItemCount(): Int {
    L.log("getItemCount $itemsListSize")
    return itemsList.size
}

Put this function outside from your adapter, and replace the new arraylist 将此功能放在适配器之外,并替换新的arraylist

fun swap(list: ArrayList<QMessage>){
    itemsList = list
    adapter.notifydatasetchanged()
}

Make sure this variable is outside from your adapter class 确保此变量在适配器类之外

private var itemsList = ArrayList<QMessage>()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 RecyclerView onCreateViewHolder未调用 - RecyclerView onCreateViewHolder not called RecyclerView onCreateViewHolder未被调用 - RecyclerView onCreateViewHolder not being called RecyclerVIew onCreateViewHolder 和 onBindViewHolder 没有被调用 - RecyclerVIew onCreateViewHolder and onBindViewHolder is not called Recyclerview onCreateViewHolder调用了每个项目 - Recyclerview onCreateViewHolder called for every item 什么时候调用onCreateViewHolder,为什么? 回收站视图 - When is onCreateViewHolder called and why? RecyclerView Android Kotlin RecyclerView 适配器 onCreateViewHolder 未调用 - Android Kotlin RecyclerView Adapter onCreateViewHolder no called RecyclerView中没有调用适配器的onCreateViewHolder和onBindViewHolder方法? - Adapter onCreateViewHolder and onBindViewHolder methods are not getting called in RecyclerView? 调用 getItemCount 时 RecyclerView 未调用 onCreateViewHolder 方法 - RecyclerView is not calling onCreateViewHolder method while getItemCount is called Recyclerview - 为每个列表项调用 onCreateViewHolder - Recyclerview - onCreateViewHolder called for each list item 垂直recyclerview中的水平RecyclerView不起作用,从未调用过onCreateViewHolder - horizontal RecyclerView inside a vertical recyclerview is not working, onCreateViewHolder never called
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM