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

来源:互联网 发布:软件开发常用软件 编辑:程序博客网 时间:2024/05/28 15:08

如果你在界面中使用了RecyclerView,并且添加了上拉加载和下拉刷新的功能的话,一定对这个异常不会陌生。因为这个异常就时常发生在刷新清除数据的时候,刚好上拉加载的也调用了notifyDataSetChange();

然后就会跑出如下异常:

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 6(offset:6).state:9at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java)at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java)at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java)at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java)at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java)at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java)at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java)at android.support.v7.widget.RecyclerView.scrollByInternal(RecyclerView.java)at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java)at android.view.View.dispatchTouchEvent(View.java:7706)
所以,要怎么避免这个bug呢?这就需要把上拉加载和下拉刷新区分开来,让着两个不再同一时间发生。但是我们没有办法去阻止用户去做这样的操作,所以只能在代码上下功夫。我们举个例子


public class FragmentKaifuTodayAndTomorrow extends BaseFragment implements OnRefreshListener, ItemKaiFuKaiCeFragmentLayout.OnClickRemindListener, UserManager.IOnLogin, UserManager.IOnLoginOut {        private SwipeRefreshLayout mSwipeRefreshLayout;    private RecyclerView mRecyclerView;    private AdapterKaiFuKaiCeTodayAndTomorrow mAdapter;    private LinearLayoutManager mLinearLayoutManager;    private ArrayList<KaiFuKaiCeBean> mDatas = new ArrayList<KaiFuKaiCeBean>();    private ProtocolHomeKaiFuKaiCe mProtocolHomeKaiFuKaiCe;//获取数据        private FootView mFootView;    private boolean mIsLoadingMore;//是否在加载更多数据      //下拉加载更多数据时候的网络请求    private void getMoreData() {        mIsLoadingMore = true;//开始请求的时候就置true标志正在加载        mProtocolHomeKaiFuKaiCe = new ProtocolHomeKaiFuKaiCe(getActivity(), mDatas.size(), Constants.SIZE, mType, new ProtocolBase.IProtocolListener() {            @Override            public void onSuccess(Object resultData) {                if (!getActivity().isFinishing()) {                    mFootView.invisible();                    int start = mDatas.size();                    if (mProtocolHomeKaiFuKaiCe.mDatas.size() > 0) {                        mDatas.addAll(mProtocolHomeKaiFuKaiCe.mDatas);                        mAdapter.notifyItemRangeInserted(start, mProtocolHomeKaiFuKaiCe.mDatas.size());                    } else {                        mFootView.hide();                        ToastUtils.showLongToast(getActivity(), "没有更多数据");                    }                    mProtocolHomeKaiFuKaiCe = null;                                       mIsLoadingMore = false;//请求更多数据成功了,并且notifyItemRangeInserted之后就置false标识已
                                          //经添加完数据                }            }            @Override            public void onFailure(int state,boolean hasCache, String errMsg) {                if (!getActivity().isFinishing()) {                    ToastUtils.showLongToast(getActivity(), errMsg);                    mIsLoadingMore = false;//请求数据失败了,也要更改加载标识                }            }        });        mProtocolHomeKaiFuKaiCe.postRequest();    }    @Override    public void onRefresh() {        if(mIsLoadingMore){//加载更多数据的时候不执行刷新数据请求            mSwipeRefreshLayout.setRefreshing(false);            return;        }        loadData(getContext());//刷新数据    }    @Override    protected void initViews(View convertView) {               mSwipeRefreshLayout = (SwipeRefreshLayout) convertView.findViewById(R.id.activity_kaifukaice_layout_refresh);        mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_green_light, android.R.color.holo_blue_bright, android.R.color.holo_orange_light, android.R.color.holo_red_light);        mRecyclerView = (RecyclerView) convertView.findViewById(R.id.activity_kaifukaice_layout_recyclerview);        mLinearLayoutManager = new LinearLayoutManager(getContext());        mRecyclerView.setLayoutManager(mLinearLayoutManager);        mFootView = new FootView(getContext(), mRecyclerView);        mAdapter = new AdapterKaiFuKaiCeTodayAndTomorrow(getContext(), mDatas,mType);        mAdapter.setFooterView(mFootView.getView());        mRecyclerView.setAdapter(mAdapter);        mSwipeRefreshLayout.setOnRefreshListener(this);        mAdapter.setOnClickRemindListener(this);        mRecyclerView.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                return null != mSwipeRefreshLayout && mSwipeRefreshLayout.isRefreshing();//刷新的时候不加载更多数据,刷新的时候控制列表不可滑动            }        });           }}
这样就实现了对上拉加载滚动和下拉刷新数据请求的控制,使他们不会在同一时间发生,从而避免的异常。

阅读全文
0 0
原创粉丝点击