最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Android RecyclerView上拉加载更多功能回弹实现代码
时间:2017-04-01 编辑:简简单单 来源:一聚教程网
实现原理是使用RecyclerView的OnTouchListener方法监听滑动 在adapter里面增加两项footview 其中date.size为显示的加载条,可以自定义,date.size+1为空白的View,我们设置其高度为0 我们通过LinearLayoutManager的 findLastVisibleItemPosition判断显示的最后一条数据,如果是空白view,表示加载条已经完全展示,松开即可刷新。
回弹效果是通过在滑动时动态改变空白view的高度,达到阻尼效果 ,回弹时再动态将其改为0,达到回弹效果,通过loading防止加载过程中滑动导致显示问题 这里的回调采用了Runnable传参
代码如下 | 复制代码 |
publicclassRefreshFootAdapterextends RecyclerView.Adapter // 上拉加载更多 publicstaticfinalintSATUS_PULLUP_LOAD_MORE =0; // 正在加载中 publicstaticfinalintSATUS_LOADING_MORE =1; publicstaticfinalintSATUS_UP_LOADING_MORE =2; // 上拉加载更多状态-默认为0 privateintload_more_status =0; privateLayoutInflater mInflater; privateList privatestaticfinalintTYPE_ITEM =0;// 普通Item View privatestaticfinalintTYPE_FOOTER =1;// 底部FootView privatestaticfinalintTYPE_FOOTER_EMPTY =2;// 底部空白View privatestaticintpagesize; privateinteview_height =1; privatelongTimeFlag;// 回弹时间 privateRecyclerView parent; privatebooleanloadmare;// 判断当前是可加载更多 privatebooleanloading;// 判断是否正在加载 privateintstartY, nowY;// 滑动判断 //构造函数 处理滑动监听 更新等功能 publicRefreshFootAdapter(Context context, RecyclerView parent, finalLinearLayoutManager linearLayoutManager,intpagesize, finalRunnable onloadmore) { this.parent = parent; this.mInflater = LayoutInflater.from(context); this.mTitles =newArrayList for(inti =0; i<20; i++) { intindex = i +1; mTitles.add("item"+ index); } this.pagesize = pagesize; parent.setOnTouchListener(newOnTouchListener() { @Override publicbooleanonTouch(View v, MotionEvent ev) { // TODO Auto-generated method stub switch(ev.getAction()) { caseMotionEvent.ACTION_MOVE: nowY = (int) ev.getY(); if(RefreshFootAdapter.this.getItemCount() == linearLayoutManager .findLastVisibleItemPosition() +1) { if(startY ==0) {// 按下 startY = nowY; } intchangeY = nowY - startY; RefreshFootAdapter.this .notifyEmptyView((int) (-changeY /1.3f)); if(loading) { returnfalse; } RefreshFootAdapter.this .changeMoreStatus(RefreshFootAdapter.this.SATUS_UP_LOADING_MORE); loadmare =true; }else{ loadmare =false; if(loading) { returnfalse; } RefreshFootAdapter.this .changeMoreStatus(RefreshFootAdapter.this.SATUS_PULLUP_LOAD_MORE); // 普通的滑动 startY =0; } break; caseMotionEvent.ACTION_UP: RefreshFootAdapter.this.resetEmptyView(); if(loadmare) { if(loading) { returnfalse; }else{ RefreshFootAdapter.this .changeMoreStatus(RefreshFootAdapter.this.SATUS_LOADING_MORE); if(onloadmore !=null&& !loading) { loading =true; onloadmore.run(); } } } startY =0; break; default: break; } returnfalse; } }); } /** * item显示类型 * * @param parent * @param viewType * @return */ publicRecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, intviewType) { // 进行判断显示类型,来创建返回不同的View if(viewType == TYPE_ITEM) { View view = mInflater.inflate(R.layout.item_recycler_layout, parent,false); // 这边可以做一些属性设置,甚至事件监听绑定 // view.setBackgroundColor(Color.RED); ItemViewHolder itemViewHolder =newItemViewHolder(view); returnitemViewHolder; }elseif(viewType == TYPE_FOOTER) { View foot_view = mInflater.inflate( R.layout.recycler_load_more_layout, parent,false); // 这边可以做一些属性设置,甚至事件监听绑定 // view.setBackgroundColor(Color.RED); FootViewHolder footViewHolder =newFootViewHolder(foot_view); returnfootViewHolder; }elseif(viewType == TYPE_FOOTER_EMPTY) { View foot_view_empty = mInflater.inflate( R.layout.recycler_load_more_layout_empty, parent,false); // 这边可以做一些属性设置,甚至事件监听绑定 // view.setBackgroundColor(Color.RED); FootEmptyHolder footEmptyViewHolder =newFootEmptyHolder( foot_view_empty); returnfootEmptyViewHolder; } returnnull; } /** * 数据的绑定显示 * * @param holder * @param position */ publicvoidonBindViewHolder(RecyclerView.ViewHolder holder,intposition) { if(holderinstanceofItemViewHolder) { ((ItemViewHolder) holder).item_tv.setText(mTitles.get(position)); holder.itemView.setTag(position); }elseif(holderinstanceofFootViewHolder) { FootViewHolder footViewHolder = (FootViewHolder) holder; switch(load_more_status) { caseSATUS_PULLUP_LOAD_MORE: footViewHolder.foot_view_item_tv.setText("上拉加载更多..."); break; caseSATUS_LOADING_MORE: footViewHolder.foot_view_item_tv.setText("正在加载更多数据..."); break; caseSATUS_UP_LOADING_MORE: footViewHolder.foot_view_item_tv.setText("松开加载更多数据..."); break; } }elseif(holderinstanceofFootEmptyHolder) { FootEmptyHolder footViewHolder = (FootEmptyHolder) holder; footViewHolder.empty.setLayoutParams(newViewGroup.LayoutParams( 111, eview_height)); } } /** * 进行判断是普通Item视图还是FootView视图 * * @param position * @return */ @Override publicintgetItemViewType(intposition) { // 最后一个item设置为footerView if(position +1== getItemCount()) { returnTYPE_FOOTER_EMPTY; }elseif(position +2== getItemCount()) { returnTYPE_FOOTER; }else{ returnTYPE_ITEM; } } //如果是页数的倍数 itemcount+2 @Override publicintgetItemCount() { if(mTitles.size() % pagesize !=0) { returnmTitles.size(); }else{ returnmTitles.size() +2; } // return mTitles.size()+1; } // 自定义的ViewHolder,持有每个Item的的所有界面元素 publicstaticclassItemViewHolderextendsRecyclerView.ViewHolder { publicTextView item_tv; publicItemViewHolder(View view) { super(view); item_tv = (TextView) view.findViewById(R.id.item_tv); } } /** * 底部FootView布局 */ publicstaticclassFootViewHolderextendsRecyclerView.ViewHolder { privateTextView foot_view_item_tv; publicFootViewHolder(View view) { super(view); foot_view_item_tv = (TextView) view .findViewById(R.id.foot_view_item_tv); } } //空白项 publicstaticclassFootEmptyHolderextendsRecyclerView.ViewHolder { privateView empty; publicFootEmptyHolder(View view) { super(view); empty = view.findViewById(R.id.empty); } } // 添加数据 publicvoidaddItem(List // mTitles.add(position, data); // notifyItemInserted(position); newDatas.addAll(mTitles); mTitles.removeAll(mTitles); mTitles.addAll(newDatas); notifyDataSetChanged(); } //更新添加数据 publicvoidaddMoreItem(List mTitles.addAll(newDatas); notifyDataSetChanged(); } //更新空白项高度 privatevoidnotifyEmptyView(intheight) { this.eview_height = height; notifyItemChanged(getItemCount() -1); } //空白回弹 伪回弹动画 privatevoidresetEmptyView() { finalintdx = eview_height; newThread(newRunnable() { @Override publicvoidrun() { // TODO Auto-generated method stub finalinttime =500; finallongstartTime =newDate().getTime(); TimeFlag = startTime; longnowTime =newDate().getTime(); while(startTime + time > nowTime && TimeFlag == startTime) { nowTime =newDate().getTime(); finalintdt = (int) (nowTime - startTime); parent.post(newRunnable() { @Override publicvoidrun() { // TODO Auto-generated method stub eview_height = eview_height * (time - dt) / time; notifyDataSetChanged(); } }); try{ Thread.sleep(10); }catch(InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } parent.post(newRunnable() { @Override publicvoidrun() { // TODO Auto-generated method stub eview_height =0; notifyDataSetChanged(); } }); } }).start(); } //停止加载更多 重置loading状态和显示文本 publicvoidstopLoadMore() { notifyDataSetChanged(); loading =false; RefreshFootAdapter.this .changeMoreStatus(RefreshFootAdapter.this.SATUS_PULLUP_LOAD_MORE); } //改变加载条状态 privatevoidchangeMoreStatus(intstatus) { if(loading) { return; } load_more_status = status; notifyDataSetChanged(); } } |
图1为滑动过程
图2为松开加载
相关文章
- sora软件价格介绍 02-22
- sora官网入口地址一览 02-22
- Sora生成的视频使用教程 02-22
- 《梦幻西游》元宵灯谜线索答案大全2024 02-22
- 《原神》有朋自远方来第一天通关攻略 02-22
- 《苏醒之路》四个结局达成攻略 02-22