最近打算用recyclerview做一个上下拉刷新加载的列表,看了好多,终于让我找到一个容易理解,并且功能齐全的代码
感谢http://blog.csdn.net/goodchangyong/article/details/51324183给我的启发,顺藤摸瓜,开始获取列表数据,然后就是各种解析,结果大吃一惊,竟然一下加载了两遍数据,
不解释,bug常用手段,debug上,终于在适配器里边发现一个严重的错误,因为上边那个例子是假数据,适配器和activity里边都添加了数据,适配器是进入界面的数据,activity是刷新加载的数据,当然不会出bug,代码如下:
错误原因就在于public void setOnRefreshDatas(List<DataListBean> mDatas){ mDatas.addAll(this.mDatas); this.mDatas.removeAll(this.mDatas); // this.mDatas.clear(); this.mDatas.addAll(mDatas); notifyDataSetChanged(); }
mDatas.addAll(this.mDatas);
mDatas是刷新之后的数据,this.mDatas是初始化界面的数据,两者叠加,可不就是两次数据嘛,我滴个乖乖,例子终归是例子,还需要自己改呀,继续试,结果,果不其然,问题又来了,进入初始化界面,进行加载没问题,刷新没问题,在加载,咦,数据呢?
没办法继续找问题吧;一行代码神奇的地方出现了
/**recyclerview的滑动监听*/ demo_recycler.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); /**通过LinearLayoutManager获取可见视图的最后一个item * 的position*/ item_index = manager.findLastVisibleItemPosition(); } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); /**加载更多*/ if(newState == RecyclerView.SCROLL_STATE_IDLE && item_index + 1 == adapter.getItemCount()){ new Handler().postDelayed(new Runnable() { @Override public void run() { // List<String> mDatas = new ArrayList<String>(); // for (int i = 0; i <= 5; i++){ // int index = i + 1; // mDatas.add("第" + index + "行有更多数据啦"); // } setDatas(pageNo); ToastUtil.showShort(getApplicationContext(), "加载"); // adapter.setLoadMoreDatas(mDatas); } }, 1500); } } }); }
onScrolled和onScrollStateChanged运行顺序呢,找度娘
原理:判断在 newState == RecyclerView. SCROLL_STATE_IDLE 之前已经运行了 onScrolled方法SCROLL_STATE_TOUCH_SCROLL#手接触ScrollView触发一次 SCROLL_STATE_FLING#正在滚动 SCROLL_STATE_IDLE#滑动停止 ListView 图片列表的滚动,应该在 SCROLL_STATE_FLING 时让图片不显示,提高滚动性能让滚动小姑更平滑 SCROLL_STATE_IDLE 时显示当前屏幕可见的图片 [java] view plain copy newAbsListView.OnScrollListener(){ @Override publicvoid onScrollStateChanged(AbsListView absListView, intscrollState) { switch(scrollState) { caseAbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: // 手指触屏拉动准备滚动,只触发一次 顺序: 1 break; caseAbsListView.OnScrollListener.SCROLL_STATE_FLING: // 持续滚动开始,只触发一次 顺序: 2 break; caseAbsListView.OnScrollListener.SCROLL_STATE_IDLE: // 整个滚动事件结束,只触发一次 顺序: 4 break; default: break; } } @Override publicvoid onScroll(AbsListView absListView, inti, inti1, inti2) { // 一直在滚动中,多次触发 顺序: 3 } }
也就是说if(newState == RecyclerView.SCROLL_STATE_IDLE &&item_index + 1 == adapter.getItemCount()){
那么findLastVisibleItemPosition方法难道不是每次都运行吗,如果每次都运行onScrolled应该每次都会运行findLastVisibleItemPosition啊,但是为什么,加载刷新加载之后还是第一次加载的数值而没有改变呢?没办法只能吧item_index=manager.findLastVisibleItemPosition();放在
onScrollStateChanged里边,让他随onScrollStateChanged和上拉加载一起运行了。
如果有经常用或者懂findLastVisibleItemPosition方法的,麻烦说一下,第一次写博客,
也是第一次了解recyclerview,谢谢!!!
明天进军recyclerview的表格展示