java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false is
2016-11-08 16:19
573 查看
在尝试使用LayoutTransition自定义RecyclerView的添加或者移除item的动画时,出现了此Bug.在stackoverflow找到了解决方案,在此记录备案。
先还原下问题, RecyclerView在XML中是这么定义的
<android.support.v7.widget.RecyclerView android:id="@+id/rv_content" android:layout_width="match_parent" android:layout_height="match_parent" android:animateLayoutChanges="true"> </android.support.v7.widget.RecyclerView>
先看stackoverflow中的解决方案,在答案中说到,造成错误的原因是将android:animateLayoutChanges设置为true,并且应该避免android:animateLayoutChanges属性和RecyclerView一起使用。
采用此种方案确实解决了问题,但是确实有点理解,于是翻看了官方文档,来确认下:
从RecyclerView源码中可以清晰的看到,其默认使用了DefaultItemAnimator。跟踪DefaultItemAnimator的父接口,最后发现,其最终继承于RecyclerView.ItemAnimator,该类是专门为RecyclerView的数据变化而封装的一个抽象类。
官方文档对Scrap (view)有这么一段介绍,从中可以清晰的看出,废弃的子视图与父RecyclerView完全分离,可以重复利用的,如果不需要重新绑定,则可以未修改。如果修改子视图,应该在数据显示以前,由适配器重建一个子视图。
Scrap (view): A child view that has entered into a temporarily detached state during layout. Scrap views may be reused without becoming fully detached from the parent RecyclerView, either unmodified if no rebinding is required or modified by the adapter if the view was considered dirty. Dirty (view): A child view that must be rebound by the adapter before being displayed.
如果想自定义Item动画,需调用setItemAnimator(RecyclerView.ItemAnimator animator)方法,其参数为RecyclerView.ItemAnimator,而其本身与LayoutTransition就没有联系,也就是说从一开始想法就错了。
接着再看看官方文档对于LayoutTransition的介绍,可以清晰的看到LayoutTransition的动画效果,只有当ViewGroup中有View添加、删除、隐藏、显示的时候才会体现出来。
从另一方面来说,RecyclerView是对数据的显示,并未增加或减少控件。在RecyclerView的适配数据发生改变时,其Adapter回重建子视图,鉴于RecyclerView的内部缓存,子视图会重复利用,但并不是真正意义的增加或删除控件,即使不冲突,我想应该也不会出现动画效果。如果想实现RecyclerView的Item的动画效果,应该采用LayoutAnimation,一开始方向就错了,所以Bug也就出现了。
参考资料:
1. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html
2. http://stackoverflow.com/questions/26477660/recyclerview-crashes-when-scrapped-or-attached-views-may-not-be-recycled
相关文章推荐
- java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false is
- java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false is
- java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false is
- java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false is
- java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false is
- IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false isAttached:t
- java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled.
- RecyclerView 报Scrapped or attached views may not be recycled. as Scrap:false isAttached:true异常
- Scrapped or attached views may not be recycled. isScrap:false isAttached:true错误
- Scrapped or attached views may not be recycled. isScrap:false isAttached:true异常
- java.lang.IllegalArgumentException: Host name may not be null:
- android之“java.lang.IllegalArgumentException: Window type can not be changed after the window is add”
- Scrapped or attached views may not be recycled
- 关于网络请求的一个异常bug(java.lang.IllegalArgumentException: Host name may not be null)
- java.lang.IllegalArgumentException: Host name may not be null
- java.lang.IllegalArgumentException: Window type can not be changed after the window is added.
- java.lang.IllegalArgumentException: Document base XXXXX does not exist or is not a readable directory
- decorview that was originally added here or java.lang.IllegalArgumentException: View not attached to window manager
- java.lang.IllegalArgumentException: Document base *** does not exist or is not a readable
- 使用Activity.isfinishing()解决java.lang.IllegalArgumentException: View not attached to window manager