在notifyItemRangeInserted之后没有调用RecyclerView onCreateViewHolder

时间:2018-01-18 03:42:08

标签: android android-recyclerview recycler-adapter

这是我的recyclerView init:

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

这里一切正常。

当我收到新数据列表时,我试图在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)
}

我知道它建议在单独的线程中使用,但只是例如diffUtill在ui线程中工作

因此,每当有一些数据更新时,我都会收到所有消息的新列表。

问题,当我已经有很少的消息(例如两个),并且它们大于一个屏幕(我们需要滑动以查看它们已满)并且接收第三个 - 适配器没有& #39; t滚动到底部。但即使我手动完成,也没有第三条消息!直到我刷了一些然后再向下滑动!

有人熟悉这种吗?

任何想法为什么会发生以及如何解决?

更新: 的 顺便说一句,下一次交换数据的行为相同:

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

更新2: 只是在插入getItemCount后返回正确的列表大小(因此调用了这个方法)的日志,但插入后没有调用onCreateViewHolder

更新3:     这是我的适配器:     class 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)
    }

}

更新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

我们可以看到,在第二次交换后没有onCreateViewHolder调用

1 个答案:

答案 0 :(得分:0)

只需返回itemsList.size即可

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

将此功能放在适配器外面,并替换新的arraylist

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

确保此变量位于适配器类之外

private var itemsList = ArrayList<QMessage>()