RecyclerView异常BUG

xiaoxiao2021-02-28  85

05-05 11:47:52.021 4882-4882/com.daijintao.youjin E/AndroidRuntime: FATAL EXCEPTION: main Process: com.daijintao.youjin, PID: 4882 java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{184736a1 position=1 id=-1, oldPos=1, pLpos:-1 scrap [attachedScrap] tmpDetached no parent} at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5297) at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5479) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5440) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5436) at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2224) at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1551) at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1511) at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:595) at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3534) at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3019) at android.view.View.measure(View.java:17547) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) at android.widget.LinearLayout.measureVertical(LinearLayout.java:722) at android.widget.LinearLayout.onMeasure(LinearLayout.java:613) at android.view.View.measure(View.java:17547) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) at android.widget.LinearLayout.measureVertical(LinearLayout.java:722) at android.widget.LinearLayout.onMeasure(LinearLayout.java:613) at android.view.View.measure(View.java:17547) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) at android.widget.LinearLayout.measureVertical(LinearLayout.java:722) at android.widget.LinearLayout.onMeasure(LinearLayout.java:613) at android.view.View.measure(View.java:17547) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535) at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139) at android.view.View.measure(View.java:17547) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) at android.widget.LinearLayout.measureVertical(LinearLayout.java:722) at android.widget.LinearLayout.onMeasure(LinearLayout.java:613) at android.view.View.measure(View.java:17547) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535) at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) at android.view.View.measure(View.java:17547) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) at android.widget.LinearLayout.measureVertical(LinearLayout.java:722) at android.widget.LinearLayout.onMeasure(LinearLayout.java:613) at android.view.View.measure(View.java:17547) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535) at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2615) at android.view.View.measure(View.java:17547) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2015) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1173) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1379) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885) at android.view.Choreographer$Callb

这么晚了还在调试BUG实在伤不起,不过作为一个准程序员来说这点幸苦当然算不了什么。现在把今天碰到的一个比较令人不解的错误记录下来,以备日后随时翻查。 这么长一串异常信息实在很令人头疼,因为异常的地方根本没有跟自己的代码无关,所以在看了几个错误之后我放弃了,果断度娘。在几经搜索之后,终于在一篇博文中搜到了结果,这里我就引用下网上大神的原话:

文章中说到:在进行数据移除和数据增加时,务必要保证RVAdapter中的数据和移除的数据保持一致!什么意思呢?我自己琢磨认为是这样的,如果你更新你的集合后,调用RVAdapter的新出现的notifyxxxx方法时,adapter 的更新预期结果和实际集合更新结果不同,那么就会出现异常了。 举个例子吧: 比如你集合remove了两条数据,但是你RVAdapter只notifyItemRemoved(2)(这里表示移除第三条数据,只移除了一条),这种情况旧属于数据不一致了。还有一种是你增加数据,你集合增加10条数据,但是你RVAdapter的notify只增加了5条数据,这也是数据不一致。 好了,通过以上两种情况,大概就知道了,这个数据一致其实说的是要保证数量一致。就是说RVAdapter有个size,你的集合有个size。这两个size,在调用RvAdapter的notifyxxxx时候必须保持相同。

看到这里,似乎茅塞顿开,去翻看自己的代码,果然在一个不起眼的位置发现了异常。

editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { if (s.toString().equals("")) { ryHint.setVisibility(View.GONE); searchList.clear(); hintAdapter.notifyItemChanged(0); }else { //当内容清空的时候恢复初始值 loadYoujinData(s.toString()); } } });

当我们清空输入内容的时候会执行if语句的第一个判断,这里的hintAdapter调用了notifyItemChanged(0)这个方法,然后是loadYoujiData这个方法的内容,这个方法是根据输入内容去请求网络数据,以下是这个方法里的关键部分,这里我使用了Bmob后端云作为我的云端服务器。

youjinBmobQuery.findObjects(new FindListener<Youjin>() { @Override public void done(List<Youjin> list, BmobException e) { if (e == null) { if (list.size() == 0) { //返回数据大小为0 Toast.makeText(MainActivity.this, "数据不存在", Toast.LENGTH_SHORT).show(); } else { ryHint.setVisibility(View.VISIBLE); //设置RecyclerView searchList.clear(); searchList.addAll(list); for(Youjin youjin:searchList){ Log.i("TAG",youjin.getName()); } hintAdapter.notifyDataSetChanged(); } } else { Toast.makeText(MainActivity.this, "加载错误", Toast.LENGTH_SHORT).show(); Log.i("TAG", "加载错误:" + e.getMessage().toString()); }

可以看到这里的adapter使用了notifyDataSetChaned(); 这样写导致的结果就是两次notifyXXX时所更新的数据和实际不一致,当我把两个调用notifyXXX的地方对调notifyXXX方法后发现错误仍然存在,而两处调用同一个notify方法,异常却没有了。

以上只是我个人的看法,欢迎大家多多指点,指出错误的地方,让小弟我及时查漏补缺。

转载请注明原文地址: https://www.6miu.com/read-44279.html

最新回复(0)