Home » Android » android – RecyclerView crashes when "scrapped or attached views may not be recycled"

android – RecyclerView crashes when "scrapped or attached views may not be recycled"

Posted by: admin March 11, 2020 Leave a comment


I’m using a simple implementation of RecyclerView taken from the Android website using a StaggeredGridLayoutManager and I keep getting this error that crashes my app:

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)  

By simple, I literally mean it’s the same implementation taken from this page on their website, the only difference being is that my grid item’s layout is an ImageView and a couple of TextViews, so I won’t bother reposting my code.

Anyone else getting this error and know how to deal with it?

How to&Answers:

This error is caused if in your XML you have android:animateLayoutChanges set to true and you call notifyDataSetChanged() on the RecyclerView’s adapter in the Java code.

So, just avoid using android:animateLayoutChanges with RecyclerViews.


I’ve had to deal with this crash also and in my case it had nothing to do with android:animateLayoutChanges.

The RecyclerView we were building had more than one type of views in it and some were having EditTexts in them. After a while we pinned the issue to being focus related. This bug happens while recycling EditTexts and one of them is focused.

Naturally we tried clearing the focus when new data is being bound to a recycled view but that didn’t work until android:focusableInTouchMode="true" is set on RecycleView. Actually that is the only change that was needed in the end for this issue to go away.


I removed the android:animateLayoutChanges from layout property and problem has been resolved.


Among the reasons that anyone can face this issue, check if you have set the attribute android:animateLayoutChanges="true"to the RecyclerView. This will cause the recycling and reattaching the RecyclerView’s items to fail. Remove it and assign the attribute to the RecyclerView’s parent container, such as a LinearLayout/RelativeLayout and you should see the problem go away.


It took me two days but could not get around this, in the end, I had to disable the item prefetch.

When setting the layout manager you can simply call


It made the error go away for me. Hope it will be useful for someone.


While using slimfit sticky headers i encountered this error. It was caused because of setting wrong first position. I got the answer here

public void onBindViewHolder(MainViewHolder holder, int position) {

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

  params.width = ViewGroup.LayoutParams.MATCH_PARENT;


just make sure you are passing correct value for mSectionFirstPosition


I met this issue this morning, but I am not facing the same reason as mentioned above.

Via debug I found that the item view in my ViewHolder has mParent and it’s not null, which in normal case it should be none( that’s what the log saying, “attached view may not be recycled”, I think it means that if the child view is already attached to a parent, it would some how cause failure when recyclering.)

But I didn’t attach the child view every time manually. And I found that it’s done when I try to inflate the child view in my ViewHolder, something like:

layoutInflater.inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)

And the last parameter attachToRoot should be false.

After I change it to false, I fixed my problem.

By the way, I only see this crash happened when I upgrade my support library to latest version 25.0.0. Before I was using version 23.4.0 and I don’t see this problem happening. I guess there should be something changed in the latest support library.

Hope this help.


I also encountered the same errror when scrolling on the RecyclerView: then I removed animateLayoutChanges="true" in layout file for RecyclerView then everything worked.


In my case it happened because I had a Transition running when trying to resize the RecyclerView because the software keyboard was about to show.

I fixed it my excluding the RecyclerView from the Transition by using Transition.excludeTarget(R.id.recyclerview, true);


I too was getting this error whenever i had animateLayoutChanges=”true” in layout file for RecyclerView.
Delete this attribute and error will disappear!


While in my case it was removing animateOnLayoutChange from the recyclerView that fixed the crash, I still needed the ability to animate the layout changes within the viewHolder. In order to get this to work, the LinearLayout' in the view holder needs theanimateOnLayoutChange’ to to true, but I needed to notifyItemChanged to the adapter. This then allowed both of the layoutTransition animations to kick off (for expanding and collapsing the viewHolder), and also avoids the scrapped exception. So yes, avoid putting the animateOnLayoutChange on the recylcerView and use the various notify methods to enable the default animations on view size changes.


There are a number of reason why this exception is called. In my case it was due to animations running thats why the views are still attached and could not be removed to the view. Only when the animation is finished thus the view could be removed and recycled.

There are two types of animation that could affect the recyclerview recycling.

1) Is the RecyclerView.ItemAnimator – this should not be the problem. This should be pretty much safe to use as it check for attach and scrapped views and handle recycling properly.

2) android:animateLayoutChanges="true" or TransitionManager.beginDelayedTransition() or TransitionManager.go(), etc. – These animations runs on its own and take hold of the items to animate. This result to the views being force to be attached until the animation is finished. The recyclerview do not have any knowledge of these animations since it is outside its scope. Therefore the recyclerview might try to recycle an item thinking it could be recycled properly but the problem is that these APIs are still holding on to the views until there animation is finished.

If you are using android:animateLayoutChanges="true" or TransitionManager.beginDelayedTransition() or TransitionManager.go(), etc. simply remove the RecyclerView and its children from the animation.

You can simply do this by taking hold of the Transition and calling

Transition.excludeChildren(yourRecyclerView, true)
Transition.excludeTarget(yourRecyclerView, true)


Take note that it is important to use Transition.excludeChildren() to exclude all of Recyclerview children from the animation and not just the Recyclerview itself.


I solve this problem by removing parent.addView() in onCreateViewHolder

This is my code

public MyViewHolder onCreateViewwHolder(ViewGroup parent, int viewType)  {
    Button addButton = new Button(context);
    return new MyViewHolder(addButton);

Function at android.support.v7.widget.RecyclerViewRecycler.recyclerViewHolderinternal() check whether my button has already a parent or not. Which if we add button to parent, it will be also assign RecyclerView to its mParent variable.


I saw this happen for me when I used a custom object in the ViewHolder for the RecyclerView adapter.

To fix the issue I cleared the custom object which in my case was a timer in the onViewRecycled(ViewHolder holder) for the adapter as below:

    public void onViewRecycled(ViewHolder holder) {
        if(holder instanceof  EntityViewHolder) {
            if(((EntityViewHolder)holder).timer != null) {
                ((EntityViewHolder) holder).timer.cancel();

This fixed the bug.


     * Informs the recycler whether this item can be recycled. Views which are not
     * recyclable will not be reused for other items until setIsRecyclable() is
     * later set to true. Calls to setIsRecyclable() should always be paired (one
     * call to setIsRecyclabe(false) should always be matched with a later call to
     * setIsRecyclable(true)). Pairs of calls may be nested, as the state is internally
     * reference-counted.
     * @param recyclable Whether this item is available to be recycled. Default value
     * is true.
     * @see #isRecyclable()
    public final void setIsRecyclable(boolean recyclable) {
        mIsRecyclableCount = recyclable ? mIsRecyclableCount - 1 : mIsRecyclableCount + 1;
        if (mIsRecyclableCount < 0) {
            mIsRecyclableCount = 0;
            if (DEBUG) {
                throw new RuntimeException("isRecyclable decremented below 0: " +
                        "unmatched pair of setIsRecyable() calls for " + this);
            Log.e(VIEW_LOG_TAG, "isRecyclable decremented below 0: " +
                    "unmatched pair of setIsRecyable() calls for " + this);
        } else if (!recyclable && mIsRecyclableCount == 1) {
            mFlags |= FLAG_NOT_RECYCLABLE;
        } else if (recyclable && mIsRecyclableCount == 0) {
            mFl`enter code here`ags &= ~FLAG_NOT_RECYCLABLE;
        if (DEBUG) {
            Log.d(TAG, "setIsRecyclable val:" + recyclable + ":" + this);


1、remove:remove data from list.


3、notifyItemRemoved:show animation.

4、notifyItemRangeChanged:range view size and redraw the viewHolders(onBindViewHolder methods)


In my case, I used the TransitionManager.beginDelayedTransition() before adding a view on top of the recyclerView. I removed the TransitionManager.beginDelayedTransition() and no crash.


I solved this issue by calling


in the adapter’s constructor and overriding getItemId in the adapter:

public long getItemId(int position) {
    return position;


Remove android:animateLayoutChanges="true" from recycleview or set android:animateLayoutChanges="false"


I use com.squareup.picasso.RequestCreator

public void into(android.widget.ImageView target,
             Callback callback)

to dynamically resize ImageView’s size after download picture from Internet, and saves the resized width and height to preserve the view size. I got this Exception because I saved LayoutParams in a Map, and in my onBindViewHolder, I retrieved it and directly set it to my ImageView. I fix this by use ImmutablePair<Integer, Integer> to only store ImageView’s size rather than a lot of other states, and use following code to restore it.

ViewGroup.LayoutParams params = image.getLayoutParams();
params.width = widthAndHeight.getLeft();
params.height = widthAndHeight.getRight();


For me the same bug with caused by a LayoutTransition on a higher level ViewGroup.


Let me add another possible fix for this kind of issue, please. I had the same problem with superSlim library for sticky headers in RecyclerView. I used MatrixCursor to set data to RecyclerViewCursorAdapter. The reason for this issue was ID columns equals to 0 for all headers. Hope that would help someone to save couple days of debugging.


In my case the problem was because of the incorrect implementing of this method public long getItemId(int position) (overrided from RecyclerView.Adapter method).

The old code will get two different ids for the same item (in my case it is the footer item), after fixing the implementation the issue has gone.


Workaround solution if reason of Exception is what itemView has parent.
In code, where you have notifyItemRemoved(position), remove itemView from RecyclerView:

View itemView = mRecyclerView.getLayoutManager().findViewByPosition(position);
if (itemView != null && itemView.getParent() != null) {
    ((ViewGroup) itemView.getParent()).removeView(itemView);


A Peculiar case which occured for me was that i had a view member in the adapter and i was lazy instantiating a view which there is no need to do with the recycle view.

It also goes against the recycle views principles which as your storing a reference to the view in this case. I give a quick example below:

// typically we would do this in a grid view adapter:
View v;
// ...
if(v = null){
v = LayoutInflater.inflate ...;

// Now with recycle view there is NO need to store a reference to View
// and lazy instantiate. So get rid of your View v member


this exception is not cause of




this final correct answer is just because you set a WRONG LayoutParams.

    nameLP = new LinearLayout.LayoutParams(context.getResources().getDisplayMetrics().widthPixels, LinearLayout.LayoutParams.WRAP_CONTENT);
    nameLP2 = new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT);

the nameLP is OK.
the nameLP2 occur the crash .bug is here.

I try all of answers of this page. trust me.


I had this issue because I overwrite equals() and hashcode() method of ViewHolder of RecyclerView.ViewHolder by calculating data equality and hashcode, then the recycle logic did not work and crashed, I just remove the overwrite and fixed.