Android RecyclerView上拉加載更多功能回彈實(shí)現(xiàn)代碼
實(shí)現(xiàn)原理是使用RecyclerView的OnTouchListener方法監(jiān)聽滑動(dòng) 在adapter里面增加兩項(xiàng)footview 其中date.size為顯示的加載條,可以自定義,date.size+1為空白的View,我們?cè)O(shè)置其高度為0 我們通過LinearLayoutManager的 findLastVisibleItemPosition判斷顯示的最后一條數(shù)據(jù),如果是空白view,表示加載條已經(jīng)完全展示,松開即可刷新。
回彈效果是通過在滑動(dòng)時(shí)動(dòng)態(tài)改變空白view的高度,達(dá)到阻尼效果 ,回彈時(shí)再動(dòng)態(tài)將其改為0,達(dá)到回彈效果,通過loading防止加載過程中滑動(dòng)導(dǎo)致顯示問題 這里的回調(diào)采用了Runnable傳參
public class RefreshFootAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { // 上拉加載更多 public static final int SATUS_PULLUP_LOAD_MORE = 0; // 正在加載中 public static final int SATUS_LOADING_MORE = 1; public static final int SATUS_UP_LOADING_MORE = 2; // 上拉加載更多狀態(tài)-默認(rèn)為0 private int load_more_status = 0; private LayoutInflater mInflater; private List<String> mTitles = null; private static final int TYPE_ITEM = 0; // 普通Item View private static final int TYPE_FOOTER = 1; // 底部FootView private static final int TYPE_FOOTER_EMPTY = 2; // 底部空白View private static int pagesize; private int eview_height = 1; private long TimeFlag;// 回彈時(shí)間 private RecyclerView parent; private boolean loadmare;// 判斷當(dāng)前是可加載更多 private boolean loading;// 判斷是否正在加載 private int startY, nowY;// 滑動(dòng)判斷 <span style="white-space:pre"> </span>//構(gòu)造函數(shù) 處理滑動(dòng)監(jiān)聽 更新等功能 public RefreshFootAdapter(Context context, RecyclerView parent, final LinearLayoutManager linearLayoutManager, int pagesize, final Runnable onloadmore) { this.parent = parent; this.mInflater = LayoutInflater.from(context); this.mTitles = new ArrayList<String>(); for (int i = 0; i < 20; i++) { int index = i + 1; mTitles.add("item" + index); } this.pagesize = pagesize; parent.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent ev) { // TODO Auto-generated method stub switch (ev.getAction()) { case MotionEvent.ACTION_MOVE: nowY = (int) ev.getY(); if (RefreshFootAdapter.this.getItemCount() == linearLayoutManager .findLastVisibleItemPosition() + 1) { if (startY == 0) {// 按下 startY = nowY; } int changeY = nowY - startY; RefreshFootAdapter.this .notifyEmptyView((int) (-changeY / 1.3f)); if (loading) { return false; } RefreshFootAdapter.this .changeMoreStatus(RefreshFootAdapter.this.SATUS_UP_LOADING_MORE); loadmare = true; } else { loadmare = false; if (loading) { return false; } RefreshFootAdapter.this .changeMoreStatus(RefreshFootAdapter.this.SATUS_PULLUP_LOAD_MORE); // 普通的滑動(dòng) startY = 0; } break; case MotionEvent.ACTION_UP: RefreshFootAdapter.this.resetEmptyView(); if (loadmare) { if (loading) { return false; } else { RefreshFootAdapter.this .changeMoreStatus(RefreshFootAdapter.this.SATUS_LOADING_MORE); if (onloadmore != null && !loading) { loading = true; onloadmore.run(); } } } startY = 0; break; default: break; } return false; } }); } /** * item顯示類型 * * @param parent * @param viewType * @return */ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // 進(jìn)行判斷顯示類型,來創(chuàng)建返回不同的View if (viewType == TYPE_ITEM) { View view = mInflater.inflate(R.layout.item_recycler_layout, parent, false); // 這邊可以做一些屬性設(shè)置,甚至事件監(jiān)聽綁定 // view.setBackgroundColor(Color.RED); ItemViewHolder itemViewHolder = new ItemViewHolder(view); return itemViewHolder; } else if (viewType == TYPE_FOOTER) { View foot_view = mInflater.inflate( R.layout.recycler_load_more_layout, parent, false); // 這邊可以做一些屬性設(shè)置,甚至事件監(jiān)聽綁定 // view.setBackgroundColor(Color.RED); FootViewHolder footViewHolder = new FootViewHolder(foot_view); return footViewHolder; } else if (viewType == TYPE_FOOTER_EMPTY) { View foot_view_empty = mInflater.inflate( R.layout.recycler_load_more_layout_empty, parent, false); // 這邊可以做一些屬性設(shè)置,甚至事件監(jiān)聽綁定 // view.setBackgroundColor(Color.RED); FootEmptyHolder footEmptyViewHolder = new FootEmptyHolder( foot_view_empty); return footEmptyViewHolder; } return null; } /** * 數(shù)據(jù)的綁定顯示 * * @param holder * @param position */ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof ItemViewHolder) { ((ItemViewHolder) holder).item_tv.setText(mTitles.get(position)); holder.itemView.setTag(position); } else if (holder instanceof FootViewHolder) { FootViewHolder footViewHolder = (FootViewHolder) holder; switch (load_more_status) { case SATUS_PULLUP_LOAD_MORE: footViewHolder.foot_view_item_tv.setText("上拉加載更多..."); break; case SATUS_LOADING_MORE: footViewHolder.foot_view_item_tv.setText("正在加載更多數(shù)據(jù)..."); break; case SATUS_UP_LOADING_MORE: footViewHolder.foot_view_item_tv.setText("松開加載更多數(shù)據(jù)..."); break; } } else if (holder instanceof FootEmptyHolder) { FootEmptyHolder footViewHolder = (FootEmptyHolder) holder; footViewHolder.empty.setLayoutParams(new ViewGroup.LayoutParams( 111, eview_height)); } } /** * 進(jìn)行判斷是普通Item視圖還是FootView視圖 * * @param position * @return */ @Override public int getItemViewType(int position) { // 最后一個(gè)item設(shè)置為footerView if (position + 1 == getItemCount()) { return TYPE_FOOTER_EMPTY; } else if (position + 2 == getItemCount()) { return TYPE_FOOTER; } else { return TYPE_ITEM; } } <span style="white-space:pre"> </span>//如果是頁數(shù)的倍數(shù) itemcount+2 @Override public int getItemCount() { if (mTitles.size() % pagesize != 0) { return mTitles.size(); } else { return mTitles.size() + 2; } // return mTitles.size()+1; } // 自定義的ViewHolder,持有每個(gè)Item的的所有界面元素 public static class ItemViewHolder extends RecyclerView.ViewHolder { public TextView item_tv; public ItemViewHolder(View view) { super(view); item_tv = (TextView) view.findViewById(R.id.item_tv); } } /** * 底部FootView布局 */ public static class FootViewHolder extends RecyclerView.ViewHolder { private TextView foot_view_item_tv; public FootViewHolder(View view) { super(view); foot_view_item_tv = (TextView) view .findViewById(R.id.foot_view_item_tv); } } <span style="white-space:pre"> </span>//空白項(xiàng) public static class FootEmptyHolder extends RecyclerView.ViewHolder { private View empty; public FootEmptyHolder(View view) { super(view); empty = view.findViewById(R.id.empty); } } // 添加數(shù)據(jù) public void addItem(List<String> newDatas) { // mTitles.add(position, data); // notifyItemInserted(position); newDatas.addAll(mTitles); mTitles.removeAll(mTitles); mTitles.addAll(newDatas); notifyDataSetChanged(); } <span style="white-space:pre"> </span>//更新添加數(shù)據(jù) public void addMoreItem(List<String> newDatas) { mTitles.addAll(newDatas); notifyDataSetChanged(); } <span style="white-space:pre"> </span>//更新空白項(xiàng)高度 private void notifyEmptyView(int height) { this.eview_height = height; notifyItemChanged(getItemCount() - 1); } <span style="white-space:pre"> </span>//空白回彈 偽回彈動(dòng)畫 private void resetEmptyView() { final int dx = eview_height; new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub final int time = 500; final long startTime = new Date().getTime(); TimeFlag = startTime; long nowTime = new Date().getTime(); while (startTime + time > nowTime && TimeFlag == startTime) { nowTime = new Date().getTime(); final int dt = (int) (nowTime - startTime); parent.post(new Runnable() { @Override public void run() { // 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(new Runnable() { @Override public void run() { // TODO Auto-generated method stub eview_height = 0; notifyDataSetChanged(); } }); } }).start(); } <span style="white-space:pre"> </span>//停止加載更多 重置loading狀態(tài)和顯示文本 public void stopLoadMore() { notifyDataSetChanged(); loading = false; RefreshFootAdapter.this .changeMoreStatus(RefreshFootAdapter.this.SATUS_PULLUP_LOAD_MORE); } //改變加載條狀態(tài) private void changeMoreStatus(int status) { if (loading) { return; } load_more_status = status; notifyDataSetChanged(); } }
圖1為滑動(dòng)過程
圖2為松開加載
以上所述是小編給大家介紹的Android RecyclerView上拉加載更多功能回彈實(shí)現(xiàn)代碼,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- Android ScrollView的頂部下拉和底部上拉回彈效果
- android仿QQ個(gè)人主頁下拉回彈效果
- Android界面上拉下拉的回彈效果實(shí)例代碼
- Android ReboundScrollView仿IOS拖拽回彈效果
- Android仿IOS回彈效果 支持任何控件
- Android ScrollView實(shí)現(xiàn)橫向和豎向拖動(dòng)回彈效果
- Android自定義ScrollView實(shí)現(xiàn)放大回彈效果
- Android編程ViewPager回彈效果實(shí)例分析
- Android自定義控件仿ios下拉回彈效果
- Android基于reclyview實(shí)現(xiàn)列表回彈動(dòng)畫效果
相關(guān)文章
AFURLSessionManager 上傳下載使用代碼說明
本文通過代碼給大家介紹了AFURLSessionManager 上傳下載使用說明,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-09-09Android開發(fā)實(shí)現(xiàn)ImageView加載攝像頭拍攝的大圖功能
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)ImageView加載攝像頭拍攝的大圖功能,涉及Android基于ImageView的攝像頭拍攝圖片加載、保存及權(quán)限控制等相關(guān)操作技巧,需要的朋友可以參考下2017-11-11Android多進(jìn)程間采用AIDL方式進(jìn)行通信
這篇文章主要為大家詳細(xì)介紹了Android多進(jìn)程間采用AIDL方式進(jìn)行通信,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04Android編程實(shí)現(xiàn)的微信支付功能詳解【附Demo源碼下載】
這篇文章主要介紹了Android編程實(shí)現(xiàn)的微信支付功能,結(jié)合實(shí)例形式詳細(xì)分析了Android微信支付功能的實(shí)現(xiàn)步驟與具體操作技巧,并附帶了Demo源碼供讀者下載參考,需要的朋友可以參考下2017-07-07Android開發(fā)中在TableView上添加懸浮按鈕的方法
如果直接在TableVIewController上貼Button的話會(huì)導(dǎo)致這個(gè)會(huì)隨之滾動(dòng),下面通過本文給大家分享在TableView上實(shí)現(xiàn)位置固定懸浮按鈕的兩種方法,對(duì)tableview 懸浮按鈕感興趣的朋友一起學(xué)習(xí)吧2016-11-11解析Android中如何做到Service被關(guān)閉后又自動(dòng)啟動(dòng)的實(shí)現(xiàn)方法
本篇文章是對(duì)在Android中如何做到Service被關(guān)閉后又自動(dòng)啟動(dòng)的方法進(jìn)行了詳細(xì)的分析和介紹。需要的朋友參考下2013-05-05