检测到不一致。滚动时使用RecyclerView的商品位置无效

时间:2018-01-15 09:32:02

标签: android android-recyclerview recycler-adapter

我正在调用API从服务器获取双方数据并将数据添加到RecyclerView但是每当我快速滚动时我都会收到错误

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 0(offset:0).state:10

几天前工作正常,所以我觉得这是RecyclerView的问题。只有在向下滚动后向上滚动时才会出现此问题。

我使用RecyclerView的滚动侦听器作为

 //Scroll Listener
    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            totalItemCount = mLayoutManager.getItemCount();
            lastVisibleItem = mLayoutManager.findLastCompletelyVisibleItemPosition();
            if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold) && customersList.size() > 0) {
                // End has been reached
                // Do something
                loading = true;
                //calling API
                if (!NetworkUtil.getConnectivityStatusString(getActivity()).equals(getString(R.string.not_connected_to_internet))) {
                    getCustomersList(customersList.get(totalItemCount - 1).getCreatedTs(), "2"
                            , customerDetailSearchEditText.getText().toString().trim());
                } else {
                    if (swipeRefreshLayout.isRefreshing()) {
                        swipeRefreshLayout.setRefreshing(false);
                    }
                    Toast.makeText(getActivity(), getString(R.string.network_error), Toast.LENGTH_SHORT).show();
                }
            }
        }
    });

我将RecyclerView的API和更新适配器称为

try {
                if (apiResponse.getSuccess()) {
                    for (Customers customers : apiResponse.getData().getCustomers()) {
                        if (apiResponse.getData().getCustomers() != null) {
                            if (traversalValue.equals("2")) {
                                customersList.add(customers);
                                dataChanged = "yes";
                            } else if (traversalValue.equals("1")) {
                                if (swipeRefreshLayout != null && swipeRefreshLayout.isRefreshing()) {
                                    // To remove duplicate items
                                    if (!time.equals(customers.getCreatedTs())) {
                                        customersList.add(0, customers);
                                    }
                                } else {
                                    customersList.add(customers);
                                }
                                dataChanged = "yes";
                            }
                        }
                    }
                    loading = false;
                }
                if (customersList != null && customersList.size() == 0) {
                    textViewEmptyView.setVisibility(View.VISIBLE);
                    swipeRefreshLayout.setVisibility(View.GONE);
                } else {
                    textViewEmptyView.setVisibility(View.GONE);
                    swipeRefreshLayout.setVisibility(View.VISIBLE);
                }
                if (sortValue != 0) {
                    bottomLayout.setVisibility(View.VISIBLE);
                    if (sortValue == 1 || sortValue == 2) {
                        //Sorted
                        sortSpannable = new SpannableString("Sorted by : ");
                        sortSpannable.setSpan(new RelativeSizeSpan(1.2f), 0, 9, 0); // set size
                        sortTextView.setText(sortSpannable);

                        if (sortValue == 1) {
                            sortedBySpannable = new SpannableString("Amount(Asc)");
                        } else {
                            sortedBySpannable = new SpannableString("Amount(Desc)");
                        }
                        sortTextView.append(sortedBySpannable);
                    } else if (sortValue == 3 || sortValue == 4) {
                        //Sorted
                        sortSpannable = new SpannableString("Sorted by : ");
                        sortSpannable.setSpan(new RelativeSizeSpan(1.2f), 0, 9, 0); // set size
                        sortTextView.setText(sortSpannable);

                        if (sortValue == 3) {
                            sortedBySpannable = new SpannableString("Name(A-Z)");
                        } else {
                            sortedBySpannable = new SpannableString("Name(Z-A)");
                        }
                        sortTextView.append(sortedBySpannable);
                    }
                } else {
                    bottomLayout.setVisibility(View.GONE);
                }
                if (swipeRefreshLayout != null && swipeRefreshLayout.isRefreshing()) {
                    swipeRefreshLayout.setRefreshing(false);
                }
                if (traversalValue.equals("2")) {
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            customerMainFragmentAdapter.notifyDataSetChanged();
                        }
                    });
                    if (dataChanged != null && dataChanged.equals("yes")) {
                        // recyclerView.smoothScrollToPosition(customerMainFragmentAdapter.getItemCount() + 1);
                    }
                } else if (traversalValue.equals("1")) {
                    if (dataChanged != null && dataChanged.equals("yes")) {
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                customerMainFragmentAdapter.notifyDataSetChanged();
                                recyclerView.smoothScrollToPosition(0);
                            }
                        });
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                if (swipeRefreshLayout != null && swipeRefreshLayout.isRefreshing()) {
                    swipeRefreshLayout.setRefreshing(false);
                }
            } 

完整的堆栈跟踪如下:

 E/UncaughtException: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 9(offset:9).state:10                                                                            atandroid.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5512)
                                                                         at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:285)
                                                                         at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:342)
                                                                         at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:358)
                                                                         at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:365)
                                                                         at android.support.v7.widget.GapWorker.run(GapWorker.java:396)
                                                                         at android.os.Handler.handleCallback(Handler.java:751)
                                                                         at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                         at android.os.Looper.loop(Looper.java:154)
                                                                         at android.app.ActivityThread.main(ActivityThread.java:6077)
                                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)

我已经搜索过它并尝试了许多解决方案。我的源代码的差异是

  1. 它会在同一个ArrayList上添加数据,以便刷新。
  2. 每当我们向下滚动时,它会将数据添加到RecyclerView的末尾。因此,我们无法在此处清除ArrayList
  3. 希望我已经正确地解释了我的问题,你们会帮助我。感谢。

1 个答案:

答案 0 :(得分:1)

我认为当您在适配器中调用recyclerView.smoothScrollToPosition(0)时,会再次调用侦听器的onScrolled方法,因为您过早地将加载设置为false并且您的recycleView尚未更新。

我建议您在平滑滚动到位置后设置loading = false。或者你可以打电话给recyclerLog.scrollTo(0)并跳过整个过程。