jim*_*251 57 android android-recyclerview
我正在使用RecyclerView显示项目的名称.我的行包含单行TextView.项目名称存储在List<String> mItemList.
要更改内容RecyclerView,我替换字符串mItemList并调用notifyDataSetChanged()RecyclerViewAdapter.
但是如果我尝试更改mItemListRecyclerView滚动时的内容,有时它会给我
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 157(offset:157).state:588
如果尺寸mItemList小于之前,就会发生这种情况.那么改变内容的正确方法是RecyclerView什么?这是一个错误RecyclerView吗?
这是Exception的完整堆栈跟踪:
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 157(offset:157).state:588
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:3300)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:3258)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1803)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1302)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1265)
at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1093)
at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:956)
at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:2715)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:524)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4921)
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:1027)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)
AdapterView代码:
private static class FileListAdapter extends RecyclerView.Adapter<FileHolder> {
private final Context mContext;
private final SparseBooleanArray mSelectedArray;
private final List<String> mList;
FileListAdapter(Context context, List<String> list, SparseBooleanArray selectedArray) {
mList = list;
mContext = context;
mSelectedArray = selectedArray;
}
@Override
public FileHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.file_list_item, viewGroup, false);
TextView tv = (TextView) view
.findViewById(R.id.file_name_text);
Typeface font = Typeface.createFromAsset(viewGroup.getContext().getAssets(),
viewGroup.getContext().getString(R.string.roboto_regular));
tv.setTypeface(font);
return new FileHolder(view, tv);
}
@Override
public void onBindViewHolder(FileHolder fileHolder, final int i) {
String name = mList.get(i);
// highlight view if selected
setSelected(fileHolder.itemView, mSelectedArray.get(i));
// Set text
fileHolder.mTextView.setText(name);
}
@Override
public int getItemCount() {
return mList.size();
}
}
private static class FileHolder extends RecyclerView.ViewHolder {
public final TextView mTextView;
public FileHolder(View itemView, TextView tv) {
super(itemView);
mTextView = tv;
}
}
Run Code Online (Sandbox Code Playgroud)
Coc*_*ico 17
对我来说没问题.使用NotifyDataSetChanged();
public class MyFragment extends Fragment{
private MyAdapter adapter;
// Your code
public void addArticle(){
ArrayList<Article> list = new ArrayList<Article>();
//Add one article in this list
adapter.addArticleFirst(list); // or adapter.addArticleLast(list);
}
}
public class ArticleAdapterRecycler extends RecyclerView.Adapter<ArticleAdapterRecycler.ViewHolder> {
private ArrayList<Article> Articles = new ArrayList<Article>();
private Context context;
// Some functions from RecyclerView.Adapter<ArticleAdapterRecycler.ViewHolder>
// Add at the top of the list.
public void addArticleFirst(ArrayList<Article> list) {
Articles.addAll(0, list);
notifyDataSetChanged();
}
// Add at the end of the list.
public void addArticleLast(ArrayList<Article> list) {
Articles.addAll(Articles.size(), list);
notifyDataSetChanged();
}
}
Run Code Online (Sandbox Code Playgroud)
dra*_*eet 10
只是在数据发生变化时禁止RecyclerView的滚动.
像我的代码一样:
mRecyclerView.setOnTouchListener(
new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mIsRefreshing) {
return true;
} else {
return false;
}
}
}
);
Run Code Online (Sandbox Code Playgroud)
更多关于:http://drakeet.me/recyclerview-bug-indexoutofboundsexception-inconsistency-detected-invalid-item-position-solution
尽管在接受的答案中给出了关于此问题的几个有用的超链接,RecyclerView但是滚动时的这种行为是错误的.
如果您看到此异常,则很可能在RecyclerView"更改" 内容后忘记通知适配器.人们notifyDataSetChanged()只有在将项目添加到数据集后才会调用.但是,不仅在重新填充适配器后发生不一致,而且当您删除项目或清除数据集时,应通过向适配器通知此更改来刷新视图:
public void refillAdapter(Item item) {
adapter.add(item);
notifyDataSetChanged();
}
public void cleanUpAdapter() {
adapter.clear();
notifyDataSetChanged(); /* Important */
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下,我试图清理适配器onStop(),并重新填充onStart().notifyDataSetChanged()使用后清洁适配器后我忘了打电话clear().然后,每当我将状态从更改onStop()为onStart()并且RecyclerView在数据集重新加载时快速滚动时,我看到了这个异常.如果我在没有滚动的情况下等待重新加载的结束,则不会有异常,因为这次可以顺利恢复适配器.
简而言之,RecyclerView当视图改变时,它是不一致的.如果您尝试在处理数据集中的更改时滚动视图,您会看到java.lang.IndexOutOfBoundsException: Inconsistency detected.要消除此问题,应在更改数据集后立即通知适配器.
小智 7
如果您使用,这个问题就会出现在 recyclerview
adapter.setHasStableIds(true);
Run Code Online (Sandbox Code Playgroud)
如果你这样设置,删除它,并在适配器内更新你的数据集;
如果您仍然遇到问题,请在获得新数据后使所有视图无效,然后更新数据集。
问题绝对不是因为recyclerview滚动,而是与notifyDataSetChanged()有关.我有一个回收站视图,我不断更改数据,即添加和删除数据.我每次在列表中添加项目时都在调用notifyDataSetChanged(),但是每当删除项目或清除列表时都没有刷新适配器.
所以要修复:
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 2(offset:2).state:12 at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5456)
Run Code Online (Sandbox Code Playgroud)
我在list.clear()之后调用了adapter.notifyDataSetChanged(),无论它在何处需要.
if (!myList.isEmpty()) {
myList.clear();
myListAdapter.notifyDataSetChanged();
}
Run Code Online (Sandbox Code Playgroud)
从那以后,我从未遇到异常.希望它也适用于其他人.:)
| 归档时间: |
|
| 查看次数: |
53265 次 |
| 最近记录: |