RecyclerView:检测到不一致。商品位置无效

时间:2015-05-13 16:44:42

标签: android android-layout android-recyclerview screen-rotation

我们的质量检查发现了一个错误:当旋转Android设备(Droid Turbo)时,发生了以下与RecyclerView相关的崩溃

  

java.lang.IndexOutOfBoundsException:       检测到不一致。无效的项目位置2(偏移:2).state:3

对我而言,它看起来像是RecyclerView中的一个内部错误,因为我无法想到这是由我们的代码直接造成的......

有没有人遇到过这个问题?

解决方案是什么?

一个残酷的解决方法可能是在发生异常时捕获异常,并从头开始重新创建RecyclverView实例,以避免陷入损坏的状态。

但是,如果可能的话,我想更好地理解这个问题(也许可以在源头修复它),而不是掩盖它。

这个错误不容易重现,但是当它发生时它是致命的。

完整的堆栈跟踪:

  
    

W / dalvikvm(7546):threadid = 1:线程退出,未捕获异常(组= 0x41987d40)     E / AndroidRuntime(7546):致命异常:主要     E / AndroidRuntime(7546):进程:com.oblong.mezzedroid,PID:7546     E / AndroidRuntime(7546):java.lang.IndexOutOfBoundsException:检测到不一致。无效的项目位置2(偏移量:2).state:3     E / AndroidRuntime(7546):在android.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.java:3382)     E / AndroidRuntime(7546):在android.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.java:3340)     E / AndroidRuntime(7546):在android.support.v7.widget.LinearLayoutManager $ LayoutState.next(LinearLayoutManager.java:1810)     E / AndroidRuntime(7546):在android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1306)     E / AndroidRuntime(7546):在android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1269)     E / AndroidRuntime(7546):在android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:523)     E / AndroidRuntime(7546):at org.liboid.recycler_view.RecyclerViewContainer $ LiLinearLayoutManager.onLayoutChildren(RecyclerViewContainer.java:179)     E / AndroidRuntime(7546):在android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:1942)     E / AndroidRuntime(7546):在android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2237)     E / AndroidRuntime(7546):at org.liboid.recycler_view.LiRecyclerView.onLayout(LiRecyclerView.java:30)     E / AndroidRuntime(7546):在android.view.View.layout(View.java:14946)     E / AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)     E / AndroidRuntime(7546):在android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)     E / AndroidRuntime(7546):在android.widget.FrameLayout.onLayout(FrameLayout.java:388)     E / AndroidRuntime(7546):在android.view.View.layout(View.java:14946)     E / AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)     E / AndroidRuntime(7546):在android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)     E / AndroidRuntime(7546):在android.widget.FrameLayout.onLayout(FrameLayout.java:388)     E / AndroidRuntime(7546):在android.view.View.layout(View.java:14946)     E / AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)     E / AndroidRuntime(7546):在android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)     E / AndroidRuntime(7546):在android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)     E / AndroidRuntime(7546):在android.widget.LinearLayout.onLayout(LinearLayout.java:1434)     E / AndroidRuntime(7546):at com.oblong.mezzedroid.workspace.content.bins.BinsContainerLayout.onLayout(BinsContainerLayout.java:22)     E / AndroidRuntime(7546):在android.view.View.layout(View.java:14946)     E / AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)     E / AndroidRuntime(7546):在android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)     E / AndroidRuntime(7546):在android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)     E / AndroidRuntime(7546):在android.widget.LinearLayout.onLayout(LinearLayout.java:1434)     E / AndroidRuntime(7546):在android.view.View.layout(View.java:14946)     E / AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)     E / AndroidRuntime(7546):在android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)     E / AndroidRuntime(7546):在android.widget.FrameLayout.onLayout(FrameLayout.java:388)     E / AndroidRuntime(7546):在android.view.View.layout(View.java:14946)     E / AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)     E / AndroidRuntime(7546):在android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)     E / AndroidRuntime(7546):在android.widget.FrameLayout.onLayout(FrameLayout.java:388)     E / AndroidRuntime(7546):在android.view.View.layout(View.java:14946)     E / AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)     E / AndroidRuntime(7546):在android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)     E / AndroidRuntime(7546):在android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)     E / AndroidRuntime(7546):在android.widget.LinearLayout.onLayout(LinearLayout.java:1434)     E / AndroidRuntime(7546):在android.view.View.layout(View.java:14946)     E / AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)     E / AndroidRuntime(7546):在android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)     E / AndroidRuntime(7546):在android.widget.FrameLayout.onLayout(FrameLayout.java:388)     E / AndroidRuntime(7546):在android.view.View.layout(View.java:14946)     E / AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)     E / AndroidRuntime(7546):在android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)     E / AndroidRuntime(7546):在android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)     E / AndroidRuntime(7546):在android.widget.LinearLayout.onLayout(LinearLayout.java:1434)     E / AndroidRuntime(7546):在android.view.View.layout(View.java:14946)     E / AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)     E / AndroidRuntime(7546):在android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)     E / AndroidRuntime(7546):在android.widget.FrameLayout.onLayout(FrameLayout.java:388)     E / AndroidRuntime(7546):在android.view.View.layout(View.java:14946)     E / AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)     E / AndroidRuntime(7546):在android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2132)     E / AndroidRuntime(7546):在android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1872)     E / AndroidRuntime(7546):at andro

  

45 个答案:

答案 0 :(得分:168)

我有一个(可能)相关问题 - 使用RecyclerView输入活动的新实例,但是使用较小的适配器会导致我崩溃。

在调用RecyclerView.dispatchLayout()之前,

mRecycler.clearOldPositions()可以尝试从剪贴簿中提取商品。结果是它从公共池中拉出位置高于适配器大小的项目。

幸运的是,只有在启用PredictiveAnimations的情况下才会这样做,所以我的解决方案是子类GridLayoutManagerLinearLayoutManager有同样的问题和'修复'),并覆盖{{1返回false:

supportsPredictiveItemAnimations()

答案 1 :(得分:69)

在我的情况下(在我的数据结构中删除/插入数据)我需要清除回收池,然后通知数据集已更改!

mRecyclerView.getRecycledViewPool().clear(); mAdapter.notifyDataSetChanged();

答案 2 :(得分:39)

在这种情况下,请使用notifyDataSetChanged()代替notifyItem...

答案 3 :(得分:11)

我通过延迟mRecycler.setAdapter(itemsAdapter)直到用mRecycler.addAll(items)将所有项添加到适配器后解决了这个问题并且它有效。我不明白为什么我这样做,它来自我看过的图书馆代码并看到“错误的顺序”中的那些行,我很确定这是它,如果有人可以确认它解释为什么它是所以?不确定这是否是一个有效的答案

答案 4 :(得分:11)

我有类似的问题,但不完全一样。在我的情况下,我在1点清除了传递给recyclerview的数组

mObjects.clear();

并且不调用notifyDataSetChanged,因为我不希望recyclerview立即清除视图。我在AsyncTask中重新填充了mObjects数组。

答案 5 :(得分:6)

我有同样的问题。当我快速滚动并调用API并更新数据时就会发生这种情况。在尝试所有事情以防止崩溃后,我找到了解决方案。

mRecyclerView.stopScroll();

它会起作用。

答案 6 :(得分:4)

当用户滚动时适配器中的列表清除时,会发生此错误,这将使项目持有人的位置发生变化,ui上的列表和项目之间的引用丢失,接下来将发生错误 “ notifyDataSetChanged” 请求。

修复:

查看更新列表方法。如果你做类似的事情

mainList.clear();
...
mainList.add() or mainList.addAll()
...
notifyDataSetChanged();

===> Error occur

如何修复。创建用于缓冲区处理的新列表对象,然后再将其分配给主列表

List res = new ArrayList();
…..
res.add();  //add item or modify list
….
mainList = res;
notifyDataSetChanged();

感谢Nhan Cao的帮助:)

答案 7 :(得分:4)

使用

notifyDataSetChanged()

代替

notifyItemRangeInserted(0, YourArrayList.size())

在这种情况下。

答案 8 :(得分:3)

在我修改Adapter实现以使用items数组的副本而不是引用之后,我的问题就消失了。每次我们在setItems()中显示新项目时,都会调用RecyclerView方法。

而不是:

private class MyAdapter extends RecyclerView.Adapter<ItemHolder> {
     private List<MyItem> mItems;  

    (....)

    void setItems(List<MyItem> items) {
        mItems = items;
    }
}

我做了:

void setItems(List<MyItem> items) {
    mItems = new ArrayList<>(items);
}

答案 9 :(得分:3)

我对recyclerView也有同样的问题 所以我只是在列表清除后立即通知适配器有关数据集的更改。

mList.clear();
mAdapter.notifyDataSetChanged();

mList.addAll(newData);
mAdapter.notifyDataSetChanged();

答案 10 :(得分:3)

要修复此问题,请在更新循环视图之前使用空列表调用notifyDataSetChanged()。

例如

//Method for refresh recycle view

    if (!hcpArray.isEmpty())

hcpArray.clear(); //更新回收视图列表

adapter.notifyDataSetChanged();

答案 11 :(得分:2)

您可以通过以下方式重现此崩溃

  1. 清除适配器项 list.clear()。 (不要调用notify***方法)
  2. 滚动回收器视图。

所以我假设当您从列表中删除项目并滚动而不调用通知方法时会发生此崩溃

答案 12 :(得分:2)

扩展LinearLayoutManager并捕获此错误

public class NoCrashLinearLayoutManager extends LinearLayoutManager {

    public NoCrashLinearLayoutManager(Context context) {
        super(context);
    }

    public NoCrashLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public NoCrashLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        try {
            super.onLayoutChildren(recycler, state);
        } catch (IndexOutOfBoundsException e){
            e.printStackTrace();
        }
    }
}

答案 13 :(得分:2)

此异常在API 19、21(不是新的)上引发。在Kotlin协程中,我加载了数据(在后台线程中),并在UI线程中添加并显示了它们:

adapter.addItem(item)

适配器:

var list: MutableList<Item> = mutableListOf()

init {
    this.setHasStableIds(true)
}

open fun addItem(item: Item) {
    list.add(item)
    notifyItemInserted(list.lastIndex)
}

由于某种原因,Android渲染速度不够快或其他原因,因此,我在post的{​​{1}}方法中更新了一个列表(添加,删除,更新项的事件):

RecyclerView

此异常类似于“无法在滚动回调中调用此方法。滚动回调可能在无法更改RecyclerView数据的小节和布局过程中运行。任何可能更改RecyclerView或适配器内容结构的方法调用都应推迟到下一帧。”:Recyclerview - cannot call this method in a scroll callback

答案 14 :(得分:2)

就我而言,我正在更新项目并在非UI线程中调用notifyDataSetChanged。它大部分时间都有效,但是当很多变化很快发生时,就会崩溃。当我这样做时,基本上是

activity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        changeData();
        notifyDataSetChanged();
    }
});
然后它就停止了崩溃。

答案 15 :(得分:2)

我正在改变后台RecyclerViewThread的数据。我得到了与OP相同的Exception。我在更改数据后添加了这个:

myRecyclerView.post(new Runnable() {
    @Override
    public void run() {
        myRecyclerAdapter.notifyDataSetChanged();
    }
});

希望有所帮助

答案 16 :(得分:2)

您只需在OnPostExecute()上清除列表,而不是在执行Pull to Refresh

时清除
// Setup refresh listener which triggers new data loading
        swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {

                AsyncTask<String,Void,String> task = new get_listings();
                task.execute(); // clear listing inside onPostExecute

            }
        });

我发现当您在拉动刷新期间滚动时会发生这种情况,因为我在async task之前清除了列表,导致java.lang.IndexOutOfBoundsException: Inconsistency detected.

        swipeContainer.setRefreshing(false);
        //TODO : This is very crucial , You need to clear before populating new items 
        listings.clear();

这样你就不会以不一致的方式结束

答案 17 :(得分:1)

在致电ListAdapter (androidx.recyclerview.widget.ListAdapter)之前先使用adapter.submitList(null)致电adapter.submitList(list)

adapter.submitList(null)
adapter.submitList(someDataList)

答案 18 :(得分:1)

我最近使用新的Android架构组件遇到了这个讨厌的堆栈跟踪。从本质上讲,我的ViewModel中有一个项目列表,我的Fragment使用LiveData观察这些项目。当ViewModel为数据发布新值时,Fragment会更新适配器,传入这些新数据元素并通知适配器已发生更改。

不幸的是,在将新数据元素传递给适配器时,我没有考虑到ViewModel和Adapter都指向同一个对象引用的事实!这意味着如果我更新数据并从ViewModel中调用postValue(),则会有一个非常小的窗口,可以更新数据并且尚未通知适配器!

我的修复方法是在传入适配器时实例化元素的新副本:

mList = new ArrayList<>(passedList);

通过这种超级简单的修复,您可以确保在适配器通知之前,适配器数据不会发生变化。

答案 19 :(得分:1)

在通知之前,只需删除布局管理器的所有视图。像:

myLayoutmanager.removeAllViews();

答案 20 :(得分:1)

在我的情况下,我刚删除setHasStableIds(true);

答案 21 :(得分:1)

我遇到了类似的问题而且只是想出来了。我为测试用例硬编了几个例子,但没有确保他们每个都返回一个唯一的ID,这导致了我的下面崩溃。修复ID解决了问题,希望这有助于其他人!

答案 22 :(得分:1)

我遇到了同样的情况。 并且在清除您的收藏之前通过添加代码解决了这个问题。

strtok

答案 23 :(得分:1)

当您尝试清除列表时可能会发生此问题,如果您要清除数据列表,尤其是当您使用pull to refresh尝试使用布尔标志时,将其初始化为false并在OnRefresh方法中将其设置为true,在将新数据添加到之前,如果flag为true,则清除dataList,之后将其设为false。

您的代码可能就像这样

 private boolean pullToRefreshFlag = false ;
 private ArrayList<your object> dataList ;
 private Adapter adapter ;

 public class myClass extend Fragment implements SwipeRefreshLayout.OnRefreshListener{

 private void requestUpdateList() {

     if (pullToRefresh) {
        dataList.clear
        pullToRefreshFlag = false;
     }

     dataList.addAll(your data);
     adapter.notifyDataSetChanged;


 @Override
 OnRefresh() {
 PullToRefreshFlag = true
 reqUpdateList() ; 
 }

}

答案 24 :(得分:1)

它也可能与同时多次设置适配器有关。我有一个回调方法,同时触发了5-6次,我在回调中设置了适配器,因此RecycledViewPool无法同时处理所有这些数据。这是一个很大的机会,但你最好还是检查一下。

答案 25 :(得分:0)

当我没有重新认识我时,我就发生了问题,我确实用不同的线程同时调用了两次。

  

notifyDataSetChanged

sqlite加载函数中的一个调用函数后中的一个

答案 26 :(得分:0)

将 RecyclerView 更新到最新的 1.2.1 版本。 Aaand魔法发生了!无法再破坏我的应用程序了 :) 所以.. 尝试用你的 gradle 文件中的最新版本号替换旧版本号

dependencies {
    ...
    // RecyclerView
    def recyclerview_version = "1.2.1"
    implementation "androidx.recyclerview:recyclerview:$recyclerview_version"
}

答案 27 :(得分:0)

我解决了这个问题,在获取新数据时逐个添加项目。我在适配器中使用此功能。

fs.readFile(file, 'utf8', function (err, data) {
    if (err) {
      console.log('Error: ' + err);
      return;
    }

    data = JSON.parse(data);
    console.log(data);
    res.render('index', { title: data });
});

答案 28 :(得分:0)

如果notifyItemChanged(int position),notifyItemInserted(int position) 使用而不是互相使用 当您要更新项目使用notifyItemChanged 和您要添加项目使用notifyItemInserted 时出现此问题

答案 29 :(得分:0)

我已经解决了同一问题。我将RecyclerView.Adapter设置为setHasStableIds(true),以避免项目闪烁。

我在getItemId()中使用了可重复字段(我的模型没有id字段):

override fun getItemId(position: Int): Long {
    // Error-prone due to possibly duplicate name.
    return contacts[position].name.hashCode().toLong()
}

getItemId()应该为每个项目返回唯一的ID ,因此解决方案是这样做:

override fun getItemId(position: Int): Long {
    // Contact's phone is unique, so I use it instead.
    return contacts[position].phone.hashCode().toLong()
}

答案 30 :(得分:0)

如果有人遇到相同的问题,那么我在适配器中覆盖了这两种方法,那么效果很好。

        override fun getItemId(position: Int): Long {
            return position.toLong()
        }
    
        override fun getItemViewType(position: Int): Int {
            return position
        }

答案 31 :(得分:0)

大多数答案是禁用动画或创建新的数据副本,这在我看来是过大了。他们确实可以工作,但不能解决问题的根本原因。就我而言,这是由于使用DiffUtils的方式错误。在areItemsTheSame(old, new)方法中,我没有正确实现相等性检查,因此即使新列表中有相同数量的项目,也使notifyItemRangeInserted()通知适配器。因此,请密切注意如何实现DiffUtils回调!

答案 32 :(得分:0)

我找到了 设置 mRecycler.setLayoutFrozen(真); 在swipeContainer的onRefresh方法中。

为我解决了这个问题。

swipeContainer.setOnRefreshListener(new   SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            orderlistRecycler.setLayoutFrozen(true);
            loadData(false);

        }
    });

答案 33 :(得分:0)

就我而言,我遇到了例外情况

  

java.lang.IndexOutOfBoundsException:检测到不一致。无效的视图支架适配器positionViewHolder

在我的情况下,以上答案均无效。因为我正在更新/更改适配器中的现有项目,但是我使用了

myAdapter.notifyItemInserted(position)

相反,我应该使用这个

myAdapter.notifyItemChanged(position)

注意:在插入项目时,我们应该使用notifyItemInserted();在适配器中更新项目时,我们应该使用notifyItemChanged()

答案 34 :(得分:0)

就我而言,这解决了我的问题

rv.setAdapter(null);
rv.setItemAnimator(null);

PS:我在recyclerview适配器中进行Seache过滤时会出现我的问题

答案 35 :(得分:0)

我设法解决此问题的一种方法(在带有体系结构组件的Kotlin应用程序中)是通过从存储库中获取数据后设置if (recyclerView.adapter == null) recyclerView.adapter = MyAdapter(datasource)来解决的。显然,这可能与存储库中的暂停功能有关的异步问题有关,因为当我在开始活动时第一次获取数据时,由于db中没有数据,因此它会调用REST API,一切都会顺利进行,但是之后,无法再次执行相同的查询,从而导致崩溃。

答案 36 :(得分:0)

我也遇到了错误:

原因:我试图从异步任务更新Recycler View,同时尝试获取旧的已删除的viewHolders;

代码:我按下按钮生成数据,逻辑如下

  1. 清除回收站视图中的最后一项
  2. 调用异步任务以生成数据
  3. OnPostExecute更新Recycler视图和NotifyDataSetChanged
  4. 问题:每当我在生成数据之前快速滚动

      

    检测到不一致。视图持有者适配器positionViewHolder无效   java.lang.IndexOutOfBoundsException:检测到不一致。无效的项目位置20(偏移:2).state:3

    解决方案:而不是在生成数据之前清除RecyclerView,而是将其保留,然后将其替换为新数据,即Call NotifyDatasetChanged,如下所示;

           @Override
            protected void onPostExecute(List<Objects> o) {
                super.onPostExecute(o);
                recyclerViewAdapter.setList(o);
                mProgressBar.setVisibility(View.GONE);
                mRecyclerView.setVisibility(View.VISIBLE);
            }
    

答案 37 :(得分:0)

回复很晚,但这可能会对使用此功能的人有所帮助。

请确保您的onStop或onPause方法不会清除您的任何列表

答案 38 :(得分:0)

这是一个非常讨厌的错误。

为了处理我的项目点击,我使用RecyclerView.OnItemTouchListener的实现类似于this question中找到的解决方案。

在多次刷新RecyclerView的数据源并单击某个项目后,此IndexOutOfBoundsException会使我的应用程序崩溃。单击某个项目时,RecyclerView会在内部查找正确的基础视图并返回其位置。检查源代码,我看到有一些TasksThreads被安排。简而言之,基本上它只是一些非法状态,其中两个数据源混合在一起并且没有同步,整个事情变得疯狂。

基于此,我删除了RecyclerView.OnItemTouchListener的实施,只是点击了ViewHolder Adapter的{​​{1}}:

public void onBindViewHolder (final BaseContentView holder, final int position) {

    holder.itemView.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick (View view) {

        // do whatever you like here
      }
    });

}

这可能不是最好的解决方案,但现在是无崩溃的......希望这会节省你一些时间:)。

答案 39 :(得分:0)

对我来说,在添加以下代码行后,它就起作用了:

mRecyclerView.setItemAnimator(null);

答案 40 :(得分:0)

这只是对我有用的解决方案,甚至可以尝试上述解决方案中的许多解决方案。

1。)灌输

CustomAdapter scrollStockAdapter = new CustomAdapter(mActivity, new ArrayList<StockListModel>());
list.setAdapter(scrollStockAdapter);
scrollStockAdapter.updateList(stockListModels);

2。)在适配器中编写此方法

public void updateList(List<StockListModel> list) {
stockListModels.clear();
stockListModels.addAll(list);
notifyDataSetChanged();
}

stockListModels->此列表是您在适配器中使用的列表。

答案 41 :(得分:0)

抱歉,对于迟到但完美的解决方案: 当您尝试删除特定项目时,只需调用notifydatasetchange() 并在bindviewholder中获取这些项目并删除该项目并再次添加到列表的最后一个,然后如果这是最后一个索引则删除列表位置然后删除项目。 基本上问题出在你试图从中心删除项目时。如果您从上一个索引中删除项目,那么就没有更多的回收,并且您的adpter计数是mantine(这是关键点崩溃来到这里)并且崩溃解决了下面的代码片段。

 holder.itemLayout.setVisibility( View.GONE );//to hide temprory it show like you have removed item

        Model current = list.get( position );
        list.remove( current );
        list.add( list.size(), current );//add agine to last index
        if(position==list.size()-1){// remove from last index
             list.remove( position );
        }

答案 42 :(得分:0)

add_location.removeAllViews();

            for (int i=0;i<arrayList.size();i++)
            {
                add_location.addView(new HolderDropoff(AddDropOffActivtity.this,add_location,arrayList,AddDropOffActivtity.this,this));
            }
            add_location.getAdapter().notifyDataSetChanged();

答案 43 :(得分:0)

在我的情况下,我试图在后台线程上更改我的适配器内容,但在主/ ui线程上调用notify *。

这是不可能的!强制通知强制主线程的原因是recyclerview要求你在主线程上编辑后备适配器,即使在同一个调用堆栈上也是如此。

要解决此问题,请确保适配器的每个操作以及每个notify ...调用都是在 ui /主线程上进行的!

答案 44 :(得分:0)

林特给了我一个关于不一致的建议: 我写了(onBindViewHolder()):

pholder.mRlayout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        doStuff(position);
                    }
                });

必须替换为:

pholder.mRlayout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        doStuff(pholder.getAdapterPosition());
                    }
                });

在代码中运行两个代码,然后运行Lint进行完整的解释!!