问题描述
我正在使用 RecyclerView
来显示项目的名称.我的行包含单个 TextView
.项目名称存储在 List 中.mItemList
.
I'm using RecyclerView
to display name of the items. My row contains single TextView
. Item names are stored in List<String> mItemList
.
要更改RecyclerView
的内容,我替换mItemList
中的Strings 并在RecyclerViewAdapter
上调用notifyDataSetChanged
().
To change contents of RecyclerView
, I replace Strings in mItemList
and call notifyDataSetChanged
() on RecyclerViewAdapter
.
但是如果我在 RecyclerView 滚动时尝试更改 mItemList
的内容,有时它会给我java.lang.IndexOutOfBoundsException:检测到不一致.无效的项目位置 157(offset:157).state:588
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
如果 mItemList
的大小比以前小,就会发生这种情况.那么更改 RecyclerView
内容的正确方法是什么?这是 RecyclerView
中的错误吗?
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 代码:
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;
}
}
推荐答案
该错误现已修复,如果您仍然遇到相同的异常,请确保您正在更新您的适配器数据源仅来自主线程并在其后调用适当的适配器通知方法.
The bug is fixed now, if you're still getting the same Exception, please make sure you're updating your Adapter data source only from the main thread and calling appropriate adapter notify method after it.
旧答案:这似乎是 RecyclerView
中的一个错误,据报道 此处和此处.希望它会在下一个版本中修复.
Old answer: It seems to be a bug in RecyclerView
, it's reported here and here. Hopefully it will be fixed in the next release.
这篇关于在 RecyclerView 中检测到不一致,如何在滚动时更改 RecyclerView 的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!