滚动RecyclerView获取异常: - “java.lang.IndexOutOfBoundsException:检测到不一致。无效的商品位置21“

问题描述 投票:1回答:2

我在我的应用程序中使用RecyclerViewSqlite。因为我从RecyclerView加载SQlite而不是在后台调用服务后尝试通过RecyclerView方法通知notifyDataSetChanged(),但在滚动RecyclerView时(当RecyclerView正在更新或通知时)获得意外异常。

请检查我用于通知的setAdapter()并在RecyclerView上设置适配器

  private void setAdapter() {

        if (adapter == null) {
            adapter = new EmojiAdapter(stickerArrayList, getActivity(), "Sticker", stickerIdArrayList);
            RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
            rvEmoji.setLayoutManager(mLayoutManager);
            rvEmoji.setItemAnimator(new DefaultItemAnimator());
            rvEmoji.setAdapter(adapter);
        } else {

            adapter.notifyDataSetChanged();

        }

    }

我已经尝试了所有RecyclerView.stopScroll()RecyclerView.getRecycledViewPool().clear()但问题并不缺乏

例外

java.lang.IndexOutOfBoundsException:检测到不一致。无效项目位置21(偏移量:21).state:32 at android.support.v7.widget.RecyclerView $ Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5546)at android.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView .java:5482)在android.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.java:5478)在android.support.v7.widget.LinearLayoutManager $ LayoutState.next(LinearLayoutManager.java:2215)。 android.support.v7.widget.LinealLayoutManager.fill(LinearLayoutManager.java:1502)的android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager)中的support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1542)。 java:1316)在android.sview.Choreographer上的android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1061)android.support.v7.widget.RecyclerView $ ViewFlinger.run(RecyclerView.java:4769) android.view.Choreographer.doCallb上的$ CallbackRecord.run(Choreographer.java:761)知识分子(Choreographer.java:574)在android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:747)的android.view.Handler.handleCallback(Handler)上的android.view.Choreographer.doFrame(Choreographer.java:543) .java:733)在android.app.AtoT.Thread.main(ActivityThread.java:5095)的android.os.Handler.dispatchMessage(Handler.java:95)android.os.Looper.loop(Looper.java:136) at java.lang.reflect.Method.invokeNative(Native Method)at java.lang.reflect.Method.invoke(Method.java:515)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java: 786)在dalvik.system.NativeStart.main(本地方法)的com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)

有很多类似的问题,但我没有得到预期的结果。这里是我在这里发布问题之前访问过的链接。 1. First link 2. Second link 3. Third link 4. Forth link 5. Fifth link 6. Sixth link

我已经访问了所有链接并尝试了他们最好的解决方案,但它对我不起作用..

我在RecyclerView上使用以下gradle版本

compile 'com.android.support:recyclerview-v7:26.+'

请检查我正在使用的Adapter类如下: -

public class EmojiAdapter extends RecyclerView.Adapter<EmojiAdapter.MyViewHolder> {

    private Activity activity;
    private HashMap<String, ArrayList<EmojiBean>> arrayList = new HashMap<>();
    private String sticker_emoji;
    private ArrayList<String> keyArrayList = new ArrayList<>();

    public class MyViewHolder extends RecyclerView.ViewHolder {

        private RecyclerView rvItemCreation;
        private TextView txtStickerName, txtBy, txtCreator;
        private ImageView imgForward, imgDownload;

        private MyViewHolder(View view) {
            super(view);

            rvItemCreation = (RecyclerView) view.findViewById(R.id.rvItemCreation);
            txtStickerName = (TextView) view.findViewById(R.id.txtStickerName);
            txtBy = (TextView) view.findViewById(R.id.txtBy);
            txtCreator = (TextView) view.findViewById(R.id.txtCreator);
            imgForward = (ImageView) view.findViewById(R.id.imgForward);
            imgDownload = (ImageView) view.findViewById(R.id.imgDownload);

            txtStickerName.setTypeface(Constant.setCustomFont(activity, "Montserrat-SemiBold.otf"));
            txtBy.setTypeface(Constant.setCustomFont(activity, "Montserrat_Regular.otf"));
            txtCreator.setTypeface(Constant.setCustomFont(activity, "Montserrat_Regular.otf"));

        }
    }


    public EmojiAdapter(HashMap<String, ArrayList<EmojiBean>> arrayList, Activity activity, String sticker_emoji, ArrayList keyArrayList) {
        this.arrayList = arrayList;
        this.activity = activity;
        this.sticker_emoji = sticker_emoji;
        this.keyArrayList = keyArrayList;


    }


    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.my_media_item, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {


        if (sticker_emoji.equalsIgnoreCase("Sticker")) {
            holder.imgForward.setImageResource(R.drawable.forward_icon);
        } else {
            holder.imgForward.setImageResource(R.drawable.delete_icon);
        }


        if (arrayList.size() > position) {
            MyCreationItemAdapter mAdapter = new MyCreationItemAdapter(arrayList.get(keyArrayList.get(position)), activity);
            RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false);
            holder.rvItemCreation.setLayoutManager(mLayoutManager);
            holder.rvItemCreation.setItemAnimator(new DefaultItemAnimator());
            holder.rvItemCreation.setAdapter(mAdapter);
        }


    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }


}

请帮我解决问题。谢谢

更新 我已经做了什么来解决我已经完成的冲突,在加载数据时禁用用户界面(显示一些进度条)。

java android android-recyclerview recycler-adapter
2个回答
1
投票

我有同样的问题“java.lang.IndexOutOfBoundsException:检测到不一致。无效的项目位置6(偏移:6).state”。使用pullrefrash显示此崩溃,当你有加载时,列表比你第一次加载更多。然后你pulltorfrash新数据并清除旧的列表数据,此时你的适配器的数据大小不超过你的新数据大小。


1
投票

尝试评论这行代码:

rvEmoji.setItemAnimator(new DefaultItemAnimator());

检查它现在是否有效。如果确实如此,那么您遇到的错误是因为启用了PredictiveAnimations。要将代码与动画一起使用,您必须子类化您正在使用的特定布局管理器,并覆盖supportsPredictiveItemAnimations()方法并返回false。

@Override 
public boolean supportsPredictiveItemAnimations() { 
       return false; 
}

详细了解看看here

© www.soinside.com 2019 - 2024. All rights reserved.