K K*_*K B 47 android swipe android-recyclerview
有没有办法恢复滑动操作并在滑动完成后将视图固定器恢复到其初始位置并onSwiped在ItemTouchHelper.Callback实例上调用?我得到了RecyclerView,ItemTouchHelper并且ItemTouchHelper.Callback实例完美地协同工作,我只需要恢复滑动动作,而不是在某些情况下删除滑动项目.
Dar*_*usL 101
经过一些随机的戳后,我找到了解决方案.请求notifyItemChanged适配器.这将使刷出的视图动画回到其原始位置.
K K*_*K B 22
Google的ItemTouchHelper实施假定每个刷出的项目最终都会从回收站视图中删除,而在某些应用程序中可能不是这种情况.
RecoverAnimation是一个嵌套类,ItemTouchHelper用于管理滑动/拖动项目的触摸动画.虽然名称暗示它只能恢复项目的位置,但它实际上是唯一用于恢复(取消滑动/拖动)和替换(移出滑动或替换拖动)项目的类.奇怪的命名.
有一个名为mIsPendingCleanupin 的布尔属性RecoverAnimation,用于ItemTouchHelper确定该项是否正在等待删除.因此ItemTouchHelper,在将RecoverAnimation项目附加到项目后,在成功滑动后设置此属性,并且只要设置了此属性,动画就不会从恢复动画列表中删除.问题是,mIsPendingCleanup将始终为刷出的项目设置,导致RecoverAnimation项目永远不会从动画列表中删除.因此,即使您在成功滑动后恢复了项目的位置,一旦触摸它,它将被发送回刷出位置 - 因为RecoverAnimation将导致动画从最新的滑出位置开始.
遗憾的是,将ItemTouchHelper类源代码复制到支持库中的相同包中,并mIsPendingCleanup从RecoverAnimation类中删除该属性.我不确定这是否可以被谷歌接受,我还没有将更新发布到Play商店,看看是否会导致拒绝,但您可能会发现支持库v22.2.1中的类源代码提到修复https://gist.github.com/kukabi/f46e1c0503d2806acbe2.
jim*_*251 19
您应该覆盖onSwiped方法ItemTouchHelper.Callback并刷新该特定项目.
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder,
int direction) {
adapter.notifyItemChanged(viewHolder.getAdapterPosition());
}
Run Code Online (Sandbox Code Playgroud)
小智 15
一个 脏的解决方法此问题的解决方案是通过调用ItemTouchHelper::attachToRecyclerView(RecyclerView)两次重新附加ItemTouchHelper ,然后调用私有方法ItemTouchHelper::destroyCallbacks().destroyCallbacks()删除项目装饰和所有侦听器,但也清除所有RecoverAnimations.
请注意,我们需要先调用itemTouchHelper.attachToRecyclerView(null)才能ItemTouchHelper认为第二次调用itemTouchHelper.attachToRecyclerView(recyclerView)是一个新的回收器视图.
有关详细信息,请查看ItemTouchHelper 此处的源代码.
变通方法示例:
RecyclerView recyclerView = findViewById(R.id.recycler_view);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
...
// Workaround to reset swiped out views
itemTouchHelper.attachToRecyclerView(null);
itemTouchHelper.attachToRecyclerView(recyclerView);
Run Code Online (Sandbox Code Playgroud)
将其视为一种肮脏的解决方法,因为此方法使用内部的,未记录的实现细节ItemTouchHelper.
更新:
从文件中ItemTouchHelper::attachToRecyclerView(RecyclerView):
如果TouchHelper已经连接到RecyclerView,它将首先与前一个分离.您可以使用null调用此方法以将其与当前的RecyclerView分离.
并在参数文档中:
要添加此帮助程序的RecyclerView实例,如果要从当前的RecyclerView中删除ItemTouchHelper,则返回null.
所以至少它部分记录在案.
LiveData在使用向 a 提供列表的情况下ListAdapter,调用notifyItemChanged不起作用。但是,我发现了一个糟糕的解决方法,其中涉及在回调中将重新附加ItemTouchHelper到回收器视图onSwiped
val recyclerView = someRecyclerViewInYourCode
var itemTouchHelper: ItemTouchHelper? = null
val itemTouchCallback = object : ItemTouchHelper.Callback {
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction:Int) {
itemTouchHelper?.attachToRecyclerView(null)
itemTouchHelper?.attachToRecyclerView(recyclerView)
}
}
itemTouchHelper = ItemTouchHelper(itemTouchCallback)
itemTouchHelper.attachToRecyclerView(recyclerView)
Run Code Online (Sandbox Code Playgroud)
使用最新的 anndroidX 软件包,我仍然遇到这个问题,因此我需要稍微调整 @jimmy0251 解决方案以正确重置该项目(他的解决方案仅适用于第一次滑动)。
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
clipAdapter.notifyItemChanged(viewHolder.adapterPosition)
itemTouchHelper.startSwipe(viewHolder)
}
Run Code Online (Sandbox Code Playgroud)
请注意,startSwipe()正确重置该项目的恢复动画。