[英]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.