"废弃或附加的视图可能无法回收"时,RecyclerView崩溃

Sta*_*ter 109 android android-recyclerview

我正在使用一个简单RecyclerView的Android网站实现,StaggeredGridLayoutManager并且我一直收到崩溃我的应用程序的错误:

java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false isAttached:true
            at android.support.v7.widget.RecyclerView$Recycler.recycleViewHolderInternal(RecyclerView.java:3501)
            at android.support.v7.widget.RecyclerView$LayoutManager.scrapOrRecycleView(RecyclerView.java:5355)
            at android.support.v7.widget.RecyclerView$LayoutManager.detachAndScrapAttachedViews(RecyclerView.java:5340)
            at android.support.v7.widget.StaggeredGridLayoutManager.onLayoutChildren(StaggeredGridLayoutManager.java:572)
            at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:1918)
            at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2155)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1021)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.support.v7.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:502)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1892)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1711)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
            at android.view.Choreographer.doCallbacks(Choreographer.java:562)
            at android.view.Choreographer.doFrame(Choreographer.java:532)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
            at android.os.Handler.handleCallback(Handler.java:725)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5041)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
            at dalvik.system.NativeStart.main(Native Method)  
Run Code Online (Sandbox Code Playgroud)

简单来说,我的意思是它与他们网站上的这个页面采用相同的实现,唯一的区别是我的网格项的布局是一个ImageView和几个TextViews,所以我不打扰重新发布我的代码.

其他人得到这个错误并知道如何处理它?

Sta*_*ter 187

如果在XML中android:animateLayoutChanges设置为true并且notifyDataSetChanged()在Java代码中调用RecyclerView的适配器,则会导致此错误.

因此,请避免使用android:animateLayoutChangesRecyclerViews.

  • 那么如何在recyclerview中使用animateLayoutChanges功能呢? (21认同)
  • 如果通过mRecyclerView.setItemAnimator(new DefaultItemAnimator())设置项目动画师,则为@ dhuma1981; 那么animateLayoutChanges不一定是真的 (4认同)

Nem*_*vic 49

我也不得不处理这次崩溃,在我的情况下,它与此无关android:animateLayoutChanges.

RecyclerView我们在建设有不止一种类型的意见,它还有一些是具有EditText在其中秒.过了一会儿,我们把问题固定在与焦点有关的问题上.这个错误发生在回收EditTexts时,其中一个是重点.

当然,我们尝试在将新数据绑定到循环视图时清除焦点但android:focusableInTouchMode="true"在设置之前不起作用RecycleView.实际上,这是此问题最终需要消除的唯一变化.

  • 很棒,解决了我在RecyclerView中使用EditTexts时遇到的与焦点相关的多个问题。谢谢! (2认同)

Öze*_*can 24

我删除了android:animateLayoutChanges布局属性,问题已解决.

  • 在父容器(相对布局)上设置了此标志。修复了问题。 (2认同)

Ram*_*yer 14

在任何人都可以面对此问题的原因中,请检查您是否已将属性android:animateLayoutChanges="true"设置为RecyclerView.这将导致回收和重新附加RecyclerView的项目失败.删除它并将属性分配给RecyclerView的父容器,例如LinearLayout/RelativeLayout,您应该看到问题消失.


Max*_*Max 11

它花了我两天但无法解决这个问题,最后,我不得不禁用项目预取.

设置布局管理器时,您只需调用即可

mGridLayoutManager.setItemPrefetchEnabled(false);

这让错误消失了.希望它对某人有用.


Jas*_*aur 8

使用slimfit粘贴头时我遇到了这个错误.这是因为错误的第一个位置造成的.我在这里得到了答案

public void onBindViewHolder(MainViewHolder holder, int position) {

  final View itemView = holder.itemView;
  final LayoutManager.LayoutParams params = LayoutManager.LayoutParams.from(itemView.getLayoutParams());

  params.setSlm(LinearSLM.ID);
  params.width = ViewGroup.LayoutParams.MATCH_PARENT;
  params.setFirstPosition(item.mSectionFirstPosition);
  itemView.setLayoutParams(params);

}
Run Code Online (Sandbox Code Playgroud)

只需确保为mSectionFirstPosition传递正确的值


Ant*_*eef 8

我今天早上遇到了这个问题,但我没有遇到与上述相同的原因.

通过调试我发现我的ViewHolder中的项目视图已经mParent且它不是null,在正常情况下它应该是none(这就是日志所说的"附加视图可能无法回收",我认为这意味着如果子视图已经附加到父母,这将是一些如何在回收时导致失败.)

但我没有每次手动附加子视图.当我尝试在ViewHolder中对子视图进行充气时,我发现它已经完成,例如:

layoutInflater.inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
Run Code Online (Sandbox Code Playgroud)

最后一个参数attachToRoot应该是false.

在我改变之后false,我解决了我的问题.

顺便说一句,我只看到当我将支持库升级到最新版本25.0.0时发生此崩溃.在我使用版本23.4.0之前,我没有看到这个问题发生.我想最新的支持库应该会有一些变化.

希望这有帮助.


小智 8

在上滚动时,我也遇到了相同的错误RecyclerView:然后,我animateLayoutChanges="true"在布局文件中删除了RecyclerView所有内容。


Arc*_*nes 7

调用此异常的原因有很多。在我的情况下,这是由于动画运行,这就是为什么视图仍然附加并且无法删除到视图的原因。只有当动画完成时,视图才能被移除和回收。

有两种类型的动画可能会影响 recyclerview 回收。

1)是RecyclerView.ItemAnimator- 这不应该是问题。这应该非常安全,因为它检查附加和废弃的视图并正确处理回收。

2)android:animateLayoutChanges="true"TransitionManager.beginDelayedTransition()或 TransitionManager.go() 等 - 这些动画自行运行并控制要动画的项目。这导致视图被强制附加,直到动画完成。recyclerview 对这些动画一无所知,因为它超出了它的范围。因此,recyclerview可能会尝试回收一个项目,认为它可以正确回收,但问题是这些 API 仍然保留视图,直到动画完成。

如果您正在使用android:animateLayoutChanges="true"TransitionManager.beginDelayedTransition()或 TransitionManager.go() 等,只需RecyclerView从动画中删除及其子项。

你可以简单地通过抓住Transition和调用来做到这一点

Transition.excludeChildren(yourRecyclerView, true)
Transition.excludeTarget(yourRecyclerView, true)
Run Code Online (Sandbox Code Playgroud)

笔记:

请注意,重要的是使用从动画中Transition.excludeChildren()排除所有Recyclerview子项而不仅仅是其Recyclerview本身。


Tun*_*i_D 6

就我而言,发生这种情况是因为Transition尝试调整RecyclerView的大小时正在运行,因为软件键盘即将显示。

我修复了Transition通过使用 排除了RecyclerView的问题Transition.excludeTarget(R.id.recyclerview, true);


小智 5

每当我在RecyclerView的布局文件中有animateLayoutChanges =“ true”时,我也都会收到此错误。删除此属性,错误将消失!

  • 不,它还没有改变 (2认同)