gpt4 book ai didi

android - RecyclerView - 在 notifiyItemInserted(0) 之后保持在 0 位置

转载 作者:行者123 更新时间:2023-11-29 00:56:32 25 4
gpt4 key购买 nike

我在我的应用程序中有一个聊天,我希望我的 RV 在新消息到来时保持在位置 0,并且第一个可见项目位置为 0,但是新消息添加在当前可见的消息上方,但可见项目保留在 View ,因此用户必须滚动才能看到新消息。

我的适配器是从 RecyclerView.Adapter<RecyclerView.ViewHolder> 扩展而来的并且我找到了一个小的 hacky 解决方案来让它工作:

private suspend fun update(newItems: List<IChatItem>) {
var recyclerViewState: Parcelable? = null
if ((recyclerView?.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition() == 0) {
recyclerViewState = recyclerView?.layoutManager?.onSaveInstanceState()
}

val diffResult = withContext(Dispatchers.Default) {
DiffUtil.calculateDiff(Diff(this.currentItems, newItems))
}

diffResult.dispatchUpdatesTo(this)

recyclerViewState?.let {
recyclerView?.layoutManager?.onRestoreInstanceState(recyclerViewState)
}
}

事情是保存 RV 状态,在 DiffUtil 完成它的工作后,恢复它。它确实有效,但现在我正在尝试实现新的适配器并从 ListAdapter 扩展我的适配器类因为它在另一个线程中启动 DiffUtil。它工作得很好,但问题是我不能在这里实现我以前的解决方案,它就是不起作用。

我试过以下:

override fun submitList(list: MutableList<IChatItem>?) {
var recyclerViewState: Parcelable? = null
if ((recyclerView?.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition() == 0) {
recyclerViewState = recyclerView?.layoutManager?.onSaveInstanceState()
}

super.submitList(list)

recyclerViewState?.let {
recyclerView?.layoutManager?.onRestoreInstanceState(recyclerViewState)
}
}

但这不再有效了。有人有解决办法吗?

PS:我发现了这个问题 - Inserting RecyclerView items at zero position - always stay scrolled to top ,但我认为这不是在适配器列表中添加空的不可见项的最佳解决方案。还有其他想法吗?

UPD:如我所想 - 因为此适配器在另一个线程中启动 DiffUtil,所以它在 DiffUtil 完成其工作之前恢复了 RV 状态。此代码有效:

override fun submitList(list: List<IChatItem>?) {
var recyclerViewState: Parcelable? = null
if ((recyclerView?.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition() == 0) {
recyclerViewState = recyclerView?.layoutManager?.onSaveInstanceState()
}


super.submitList(list)

recyclerViewState?.let {
Handler().postDelayed(
{
recyclerView?.layoutManager?.onRestoreInstanceState(recyclerViewState)
}, 1000
)
}
}

但这不是我想要的。有什么方法可以检测 DiffUtil 何时完成所有操作?

最佳答案

您可以使用 RecyclerView.AdapterDataObserver() 并处理您需要的内容。

创建实现 RecyclerView.AdapterDataObserver() 的监听器类

并在您的适配器构造函数中调用 registerAdapterDataObserver(您的监听器)

然后处理您的回调。

参见 RecyclerView.AdapterDataObserver

关于android - RecyclerView - 在 notifiyItemInserted(0) 之后保持在 0 位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54347878/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com