jimmy0251 jimmy0251 - 4 months ago 14
Android Question

Inconsistency detected in RecyclerView, How to change contents of RecyclerView while scrolling

I'm using

RecyclerView
to display name of the items. My row contains single
TextView
. Item names are stored in
List<String> mItemList
.

To change contents of
RecyclerView
, I replace Strings in
mItemList
and call
notifyDataSetChanged
() on
RecyclerViewAdapter
.

But If I try to change contents of the
mItemList
while RecyclerView is scrolling, sometimes it gives me
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 157(offset:157).state:588


This happens if size of
mItemList
is less than before. So what is the correct way to change contents of the
RecyclerView
? Is this a bug in
RecyclerView
?

Here's full stack trace of 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)


AdapterView code:

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;
}
}

Answer

It seems to be a bug in RecyclerView, it's reported here and here. Hopefully it will be fixed in the next release.

Comments