我的任务是在RecyclerView中实现物品水平物品刷卡。我实际上完成了这项任务,这要归功于ViewPager源代码和其他一些资源,但在一种情况下会遇到问题。RecyclerView,物品刷卡,java.lang.IllegalStateException
我SwipeableRecyclerView(从现在起SRV)扩展RecyclerView并实现RecyclerView.OnItemTouchListener执行的魔力,它的实际工作。它还定义了一个自定义接口SwipeListener,它定义了几个方法,对于这个问题最重要的是'onSwipe(View view,int position,boolean right)'。
我的活动提供界面到SRV的实现,并且当检测到扫动和听者方法烧制,它执行以下操作:
- 移动项目/在刷卡视图关闭屏幕正确的方向与'view.animate()。translationX(translationX)'
- 动画开始上面有一个监听器,它在onAnimationEnd,从适配器中删除指定位置的项目,并调用adapter.notifyItemRemoved(位置)
- 结果是该视图消失到了滑动的一面,然后回收站删除与它的动画行 - 所有这些工作非常好
有时出现问题时,我很快刷卡,因为在第一个动画尚未完成时,我开始刷另一行。有时,它会创建没有视图的'洞'/幻像行;有时候,我得到以下异常:
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling
和堆栈跟踪显示,adapter.notifyItemRemoved()是引起异常的方法。
对于异常问题,事件的顺序如下(从我的调试跟踪):
started for position: 11
started for position: 10
finished for position: 11
removing 11
removed 11
finished position: 10
removing 10
所以,无论是完成动画陆续展开,当其中一人删除其项目,称为notifyItemRemoved,另一个完成并呼吁删除该项目。我不确定这是如何发生的,因为它实际上是在主线程上发生的,但我猜滚动也是在动画帧中完成的,而且由于第二次移除,它以某种方式与新的计算有关。
所以,我在泡菜,我不知道该怎么做。实际上,我认为最简单的事情应该是在动画开始时禁用整个回收站视图的触摸,并且只有在滚动完成后才能再次启用它们。我无法禁用SRV,但 - 我试过setEnabled(false),可点击等,但没有任何工作。
任何帮助?
我发现使用onMoveFinished更好,因为这将考虑到物品被删除后的洗牌。 – Ljdawson 2015-04-14 14:45:36
这是否意味着,在onRemoveFinished()完成后,会执行一大堆动作?我假设(也许是错误的),删除包含整个操作... – wujek 2015-04-14 18:00:35
我测试它,它确实是这样的:在onRemoveFinished后,有一大堆onMoveFinished调用。谢谢你的提示。 – wujek 2015-04-18 22:16:07