Android 插入新项目时,RecyclerView不会滚动到顶部
我有一个RecyclerView,它允许滑动删除功能。删除后,屏幕上会显示一个小吃条,以确认删除操作,允许用户“撤消”删除操作 一切正常,直到我删除位置0处的项目,然后点击Android 插入新项目时,RecyclerView不会滚动到顶部,android,android-recyclerview,linearlayoutmanager,Android,Android Recyclerview,Linearlayoutmanager,我有一个RecyclerView,它允许滑动删除功能。删除后,屏幕上会显示一个小吃条,以确认删除操作,允许用户“撤消”删除操作 一切正常,直到我删除位置0处的项目,然后点击undo。该项目将重新插入列表中,但用户需要向上滚动才能将其恢复到视图中 我试过的 在recyclerView上设置recyclerView.isNestedScrollingEnabled“ 使用协调器布局上的layoutCoordinator.滚动到(0,0) 在recyclerView上使用recyclerView.s
undo
。该项目将重新插入列表中,但用户需要向上滚动才能将其恢复到视图中
我试过的
- 在recyclerView上设置
recyclerView.isNestedScrollingEnabled“
- 使用协调器布局上的
layoutCoordinator.滚动到(0,0)
- 在recyclerView上使用
recyclerView.smoothScrollToPosition(0)
- 在recyclerView上使用
recyclerView.scrollToPosition(0)
- 在recyclerView上使用
recyclerView.scrollTo(0,0)
- 使用
在适配器上itemAdapter.notifiyItemInserted(0)
- 在适配器上使用
itemAdapter.notifiyItemchanged(0)
- 在适配器上使用
itemAdapter.notifyDataSetChanged()
- 使用布局管理器。在 布局经理
- 创建自定义
并覆盖LayoutManager
使用我自己的实现smoothScrollToPosotion()
下面是工作原理 项目碎片 在
onCreateView
内部-这里是设置itemAdapter
和recyclerView
:
val itemAdapter = object : ItemRecyclerViewAdapter() {
override fun onItemClicked(item: Item) {
// todo
}
}
val layoutManager = LinearLayoutManager(context)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = itemAdapter
以下是我的swipeToDeleteCallback
,它使用Snackbar
操作“撤消”删除:
val swipeToDeleteCallback = object : SwipeToDeleteCallback() {
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val position = viewHolder.adapterPosition
val item = itemAdapter.currentList[position]
viewModel.deleteItem(item)
val snackBar = Snackbar.make(
recyclerView,
getString(R.string.snackbar_msg_deleted_card),
Snackbar.LENGTH_LONG
)
snackBar.setAction(R.string.snack_bar_undo) {
viewModel.restoreItem(item)
recyclerView.smoothScrollToPosition(position)
}
snackBar.show()
}
}
val itemTouchHelper = ItemTouchHelper(swipeToDeleteCallback)
itemTouchHelper.attachToRecyclerView(recyclerView)
设置从ViewModel观察到的LiveData项。更改会立即传递到适配器:
val items = viewModel.items.await()
items.observe(viewLifecycleOwner, Observer {
it?.let {
itemAdapter.setItems(it)
}
})
物品捕捉器
使用DiffulicCallback提交列表:
fun setItems(list: List<Item>?) {
adapterScope.launch {
val itemsList = when(list) {
null -> emptyList()
else -> list.sortedByDescending {
it.itemId
}
}
withContext(Dispatchers.Main) {
submitList(itemsList)
}
}
}
在这里,我正在检查项目位置是否为0
。如果是这样,则告诉适配器在位置0
插入了一个新的项目
,然后启动滚动。否则,不要做任何事情,因为0
以外的任何位置的项目都会插入,并且由于DiffUtilCallback
此临时修复程序可以工作,但滚动是“快速”的,并在日志中产生错误:
RecyclerView:在平滑滚动时越过目标位置
而且,这个解决方案并不是100%的时间都有效,它更像是60%的时间
有谁知道更好的解决方案/我遗漏的东西以及解决上述错误的方法吗
snackBar.setAction(R.string.snack_bar_undo) {
viewModel.restoreItem(item)
if (position == 0) {
itemsAdapter.notifyItemInserted(0)
recyclerView.smoothScrollToPosition(0)
}
}