成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解RecyclerView下拉刷新與上拉更多

開發(fā) 開發(fā)工具
在原來的文章中我提及了如何使用RecyclerView添加header與footer,今天我們來更深入的擴展一下使用RecyclerView實現(xiàn)常用的下拉刷新與上拉加載更多的功能。當然這些功能的實現(xiàn)也是基于前面的RecyclerView添加header與footer為基礎來實現(xiàn)的。

 [[169565]]

前言

在原來的文章中我提及了如何使用RecyclerView添加header與footer,今天我們來更深入的擴展一下使用RecyclerView實現(xiàn)常用的下拉刷新與上拉加載更多的功能。當然這些功能的實現(xiàn)也是基于前面的RecyclerView添加header與footer為基礎來實現(xiàn)的,不是很了解的可以先看看前面的文章可能能更好的幫助理解。

依賴

為了方法大家的使用我已經(jīng)把他上傳到Jcenter中了,所以大家可以調(diào)用下面的代碼了直接獲取使用: 

  1. compile 'com.idisfkj.enchancerecyclerview:mylibrary:1.1.1' 

EnhanceRecyclerView

我將這個擴展的RecyclerView命名為EnhanceRecyclerView,繼承RecyclerView。我們知道既然要實現(xiàn)下拉刷新與上拉更多自然先要實現(xiàn)頭部與尾部的布局,所以我們先利用前面的知識來為EnhanceRecycleView添加header與footer 

  1. public void initView() { 
  2.         View headerView = LayoutInflater.from(getContext()).inflate(R.layout.head_layout, null); 
  3.         View footerView = LayoutInflater.from(getContext()).inflate(R.layout.footer_layout, null); 
  4.         addHeaderView(headerView); 
  5.         addFooterView(footerView); 
  6.     } 

 其中的布局文件就不多說了,至于addHeaderView與addFooterView方法可以查看我前面的那篇文章,有詳細的介紹

設置監(jiān)聽器

既然要實現(xiàn)下拉刷新與上拉加載,自然少不了對監(jiān)聽器的處理,所以下面來詳細介紹下對監(jiān)聽器OnScrollListener與OnTouchListener的處理。

OnScrollListener

為EnhanceRecyclerView添加addOnScrollListener實現(xiàn)其中的onScrollStateChanged與onScrolled方法。

onScrolled

在onScrolled中我們主要做的是獲取EnhanceRcyclerView中item的總數(shù)量、視圖顯示中的***個item在EnhanceRecyclerView中所處的位置與視圖顯示中***一個item在EnhanceRecyclerView中所處的位置。

對于item的總數(shù)量很好獲取直接調(diào)用

 

  1. totalCount = getLayoutManager().getItemCount(); 

由于RecyclerView能實現(xiàn)LinearLayoutManager、GridLayoutManager與StaggeredGridLayoutManager不同的布局,所以另外兩個要根據(jù)不同的manager來獲取,還是看具體代碼吧 

  1. if (getLayoutManager() instanceof LinearLayoutManager) { 
  2.                     lastItem = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition(); 
  3.                     firstVisible = ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition(); 
  4.                 } else { 
  5.                     into = ((StaggeredGridLayoutManager) getLayoutManager()).findLastVisibleItemPositions(into); 
  6.                     firstInto = ((StaggeredGridLayoutManager) getLayoutManager()).findFirstVisibleItemPositions(firstInto); 
  7.                     lastItem = into[0]; 
  8.                     firstVisible = firstInto[0]; 
  9.                 } 

 onScrollStateChanged

獲取到了那三個關(guān)鍵數(shù)據(jù)以后,就可以在onScrollStateChanged中實現(xiàn)具體的邏輯,在這個方法中主要實現(xiàn)的是對上拉加載更多的處理 

  1. if (lastItem == adapter.getItemCount() + 1 && newState == RecyclerView.SCROLL_STATE_IDLE && !isLoad) { 
  2.                     ViewGroup.LayoutParams params = getFooterView(0).getLayoutParams(); 
  3.                     params.width = RecyclerView.LayoutParams.MATCH_PARENT; 
  4.                     params.height = RecyclerView.LayoutParams.WRAP_CONTENT; 
  5.                     getFooterView(0).setLayoutParams(params); 
  6.                     getFooterView(0).setVisibility(View.VISIBLE); 
  7.                     smoothScrollToPosition(totalCount); 
  8.                     isLoad = true
  9.                     loadMoreListener.onLoadMore(); 
  10.                 } 
  11.                 if (firstVisible == 0) { 
  12.                     isTop = true
  13.                 } else { 
  14.                     isTop = false
  15.                     RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams(); 
  16.                     params.width = RecyclerView.LayoutParams.MATCH_PARENT; 
  17.                     params.height = RecyclerView.LayoutParams.WRAP_CONTENT; 
  18.                     params.setMargins(0, -getHeaderView(0).getHeight(), 0, 0); 
  19.                     getHeaderView(0).setLayoutParams(params); 
  20.                 } 

 簡單說明下,核心就是判斷l(xiāng)astItem是否處在***的位置,如果是的話就繼續(xù)加載更多的操作,這里提供了一個對數(shù)據(jù)處理的接口所以只要實現(xiàn)loadMoreListener.onLoadMore();即可。

上拉加載更多核心就是這么多,其它的可以查看源碼

OnTouchListener

這個監(jiān)聽器主要是對下拉刷新進行處理。我們要分別對其中我們所熟悉的MotionEvent.ACTION_DOWN、MotionEvent.ACTION_MOVE與MotionEvent.ACTION_UP進行處理。ACTION_DOWN就是簡單的獲取按下的坐標位置,這里就不多說了,下面主要的針對另外的兩個進行簡單說明。

ACTION_MOVE

這做的邏輯就是對觸摸后的處理,根據(jù)滑動的距離來動態(tài)的改變header的文本與布局視圖的顯示。 

  1. public void touchMove(MotionEvent event) { 
  2.         endY = event.getY(); 
  3.         moveY = endY - startY; 
  4.         //防止item向上滑出 
  5.         if (moveY > 0 && !isRefreshing) { 
  6.             //防止回退文本顯示異常 
  7.             scrollToPosition(0); 
  8.  
  9.             if (getHeaderView(0).getVisibility() == GONE) 
  10.                 getHeaderView(0).setVisibility(VISIBLE); 
  11.  
  12.             RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams(); 
  13.             params.width = RecyclerView.LayoutParams.MATCH_PARENT; 
  14.             params.height = RecyclerView.LayoutParams.WRAP_CONTENT; 
  15.             //使header隨moveY的值從頂部漸漸出現(xiàn) 
  16.             if (moveY >= 400) { 
  17.                 moveY = 100 + moveY / 4; 
  18.             } else { 
  19.                 moveY = moveY / 2; 
  20.             } 
  21.             viewHeight = getHeaderView(0).getHeight(); 
  22.             if (viewHeight <= 0) 
  23.                 viewHeight = 130; 
  24.             moveY = moveY - viewHeight; 
  25.             params.setMargins(0, (int) moveY, 0, 0); 
  26.             getHeaderView(0).setLayoutParams(params); 
  27.             if (moveY > 80) { 
  28.                 text.setText(getResources().getString(R.string.release_to_refresh)); 
  29.             } else { 
  30.                 text.setText(getResources().getString(R.string.pull_to_refresh)); 
  31.             } 
  32.         } else { 
  33.             if (getHeaderView(0).getVisibility() != GONE && !isRefreshing) { 
  34.                 getHeaderView(0).setVisibility(GONE); 
  35.             } 
  36.         } 
  37.     } 

 至于下拉時與頂部的距離變化是通過設置margin來動態(tài)改變的。

ACTION_UP

***的觸摸處理就是在離開屏幕時根據(jù)滑動的距離,是否調(diào)用加載數(shù)據(jù)的接口,或者隱藏下拉刷新頭部,具體還是看代碼吧。 

  1. public void touchUp() { 
  2.         if (!isRefreshing && (endY -startY) != 0 ) { 
  3.  
  4.             RecyclerView.LayoutParams params1 = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams(); 
  5.             params1.width = RecyclerView.LayoutParams.MATCH_PARENT; 
  6.             params1.height = RecyclerView.LayoutParams.WRAP_CONTENT; 
  7.  
  8.             if (moveY >= 80) { 
  9.                 text.setText(getResources().getString(R.string.refreshing)); 
  10.                 params1.setMargins(0, 0, 0, 0); 
  11.                 isRefreshing = true
  12.                 //刷新數(shù)據(jù) 
  13.                 pullToRefresh.onRefreshing(); 
  14.             } else { 
  15.                 if (viewHeight <= 0) 
  16.                     viewHeight = 130; 
  17.                 params1.setMargins(0, -viewHeight, 0, 0); 
  18.                 getHeaderView(0).setVisibility(GONE); 
  19.             } 
  20.             getHeaderView(0).setLayoutParams(params1); 
  21.         } 
  22.     } 

 代碼中重要的地方都有指出相信都能看懂,這樣下拉與上拉的邏輯就基本實現(xiàn)了,下面來看接口的設計吧

下拉與上拉接口 

  1. public interface PullToRefreshListener { 
  2.         void onRefreshing(); 
  3.     } 
  4.  
  5.     public void setPullToRefreshListener(PullToRefreshListener pullToRefresh) { 
  6.         if (loadMoreListener == null) { 
  7.             initListener(); 
  8.         } 
  9.         this.pullToRefresh = pullToRefresh; 
  10.     } 
  11.  
  12.     public interface LoadMoreListener { 
  13.         void onLoadMore(); 
  14.     } 
  15.  
  16.     public void setLoadMoreListener(LoadMoreListener loadMoreListener) { 
  17.         if (pullToRefresh == null) { 
  18.             initListener(); 
  19.         } 
  20.         this.loadMoreListener = loadMoreListener; 
  21.     } 

 在運用是添加接口監(jiān)聽時初始化前面為EnhanceRecyclerView所設置的監(jiān)聽。

狀態(tài)重置設置

在調(diào)用下拉刷新或者上拉加載更多之后,我們?yōu)槠錁?gòu)造通用方法實現(xiàn),狀態(tài)的重置與數(shù)據(jù)的更新,方便統(tǒng)一調(diào)用。 

  1. public void setLoadMoreComplete() { 
  2.         RecyclerView.LayoutParams params = (LayoutParams) getFooterView(0).getLayoutParams(); 
  3.         params.width = 0; 
  4.         params.height = 0; 
  5.         getFooterView(0).setLayoutParams(params); 
  6.         getFooterView(0).setVisibility(View.GONE); 
  7.         this.getAdapter().notifyDataSetChanged(); 
  8.         isLoad = false
  9.     } 
  10.  
  11.     public void setRefreshComplete() { 
  12.         RecyclerView.LayoutParams params1 = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams(); 
  13.         params1.width = RecyclerView.LayoutParams.MATCH_PARENT; 
  14.         params1.height = RecyclerView.LayoutParams.WRAP_CONTENT; 
  15.         params1.setMargins(0, -getHeaderView(0).getHeight(), 0, 0); 
  16.         getHeaderView(0).setLayoutParams(params1); 
  17.         getHeaderView(0).setVisibility(GONE); 
  18.         this.getAdapter().notifyDataSetChanged(); 
  19.         isRefreshing = false
  20.     } 

 所用工作已經(jīng)完成下面來做個調(diào)用示范

使用

xml中引用 

  1. <com.idisfkj.mylibrary.EnhanceRecyclerView 
  2.         android:id="@+id/recyclerView" 
  3.         android:layout_width="match_parent" 
  4.         android:layout_height="match_parent"
  5. </com.idisfkj.mylibrary.EnhanceRecyclerView> 

 設置監(jiān)聽 

  1. mRecyclerView.setPullToRefreshListener(new com.idisfkj.mylibrary.EnhanceRecyclerView.PullToRefreshListener() { 
  2.             @Override 
  3.             public void onRefreshing() { 
  4.                 refreshData(); 
  5.             } 
  6.         }); 
  7.         mRecyclerView.setLoadMoreListener(new EnhanceRecyclerView.LoadMoreListener() { 
  8.             @Override 
  9.             public void onLoadMore() { 
  10.                 loadMoreData(); 
  11.             } 
  12.         }); 

 

refreshData()與loadMoreData()加載數(shù)據(jù)的邏輯就不展示了,只是要記住在請求網(wǎng)絡數(shù)據(jù)完之后要在他們中調(diào)用相應的mRecyclerView.setRefreshComplete()與 mRecyclerView.setLoadMoreComplete()來重置狀態(tài)。

至于其他的Adapter、LayoutManager等的設置就不多說了,與原生的RecyclerView是一樣的。 

總結(jié)

其實總的來說難點有兩個

添加header與footer。這個前面已經(jīng)攻克了,而且原理也相對簡單

實現(xiàn)觸摸與滑動監(jiān)聽邏輯。這個主要是對邏輯的理解,對整個刷新的過程做個整體分析,就能很好的理解上面的代碼。對其中視圖的動態(tài)顯示做相應的變化與接口的調(diào)用就能很好的處理這些工程。

當然上面的實現(xiàn)可能還有瑕疵,希望指出,我會相應的做修改或者你們修改后可以提交給我,我統(tǒng)一做修改,謝謝!

責任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2015-03-23 18:11:39

UITableViewswift下拉刷新

2021-12-01 10:02:57

鴻蒙HarmonyOS應用

2016-12-26 15:39:35

Android下拉刷新頭部廣告位

2018-07-02 12:49:33

刷新控件動畫

2021-09-02 10:00:42

鴻蒙HarmonyOS應用

2013-07-17 16:33:02

下拉刷新listvie滾動到底部加載Android開發(fā)學習

2017-07-25 16:08:18

AndroidRecyclervie

2013-01-18 16:48:25

拉里·佩奇Google谷歌

2015-04-22 10:57:22

androidSwipeRefres

2015-05-13 09:36:18

js模擬手機下拉刷新

2024-07-02 10:00:55

2012-03-28 22:16:54

蘋果

2023-03-27 18:33:47

客服IM消息

2009-06-16 09:41:00

2015-03-19 10:12:36

下拉刷新開源組件

2012-05-02 14:41:04

jQuery

2018-02-23 10:30:15

Linux命令網(wǎng)絡連接

2020-09-14 06:24:57

USB ID
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 91精品久久久久久久久久小网站 | 日韩中文字幕在线视频 | 久久av资源网 | 欧美操操操 | 免费国产一区 | 中文字幕在线网 | 国产精品一区二区三级 | 久久精品这里 | 久久综合国产精品 | 亚洲国产网 | 国产96色在线 | 色妹子综合网 | 夏同学福利网 | 国产成人精品免费 | 少妇一级淫片免费放播放 | 午夜ww | 日韩一区精品 | 日本不卡免费新一二三区 | 四季久久免费一区二区三区四区 | 国产精品美女久久久久久不卡 | 中文字幕成人av | 在线小视频 | 黄色三级毛片 | 久久久久久久久久久高潮一区二区 | 国产色婷婷精品综合在线手机播放 | 999国产精品视频免费 | 亚洲一区 中文字幕 | 蜜桃av鲁一鲁一鲁一鲁 | 超碰在线久 | av国产精品毛片一区二区小说 | av片免费| av免费网址 | 欧美亚洲综合久久 | 日本在线免费看最新的电影 | 国产精品高清一区二区三区 | 日韩在线精品强乱中文字幕 | 狠狠骚 | 精品国产91久久久久久 | 影音先锋中文字幕在线观看 | 一区二区三区四区国产精品 | 最新高清无码专区 |