Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 插入新项目时,RecyclerView不会滚动到顶部_Android_Android Recyclerview_Linearlayoutmanager - Fatal编程技术网

Android 插入新项目时,RecyclerView不会滚动到顶部

Android 插入新项目时,RecyclerView不会滚动到顶部,android,android-recyclerview,linearlayoutmanager,Android,Android Recyclerview,Linearlayoutmanager,我有一个RecyclerView,它允许滑动删除功能。删除后,屏幕上会显示一个小吃条,以确认删除操作,允许用户“撤消”删除操作 一切正常,直到我删除位置0处的项目,然后点击undo。该项目将重新插入列表中,但用户需要向上滚动才能将其恢复到视图中 我试过的 在recyclerView上设置recyclerView.isNestedScrollingEnabled“ 使用协调器布局上的layoutCoordinator.滚动到(0,0) 在recyclerView上使用recyclerView.s

我有一个RecyclerView,它允许滑动删除功能。删除后,屏幕上会显示一个小吃条,以确认删除操作,允许用户“撤消”删除操作

一切正常,直到我删除位置0处的项目,然后点击
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)
                }
            }