日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
詳解RecyclerView下拉刷新與上拉更多

前言

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

依賴

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

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

EnhanceRecyclerView

我將這個擴(kuò)展的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方法可以查看我前面的那篇文章,有詳細(xì)的介紹

設(shè)置監(jiān)聽器

既然要實現(xiàn)下拉刷新與上拉加載,自然少不了對監(jiān)聽器的處理,所以下面來詳細(xì)介紹下對監(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)聽器主要是對下拉刷新進(jìn)行處理。我們要分別對其中我們所熟悉的MotionEvent.ACTION_DOWN、MotionEvent.ACTION_MOVE與MotionEvent.ACTION_UP進(jìn)行處理。ACTION_DOWN就是簡單的獲取按下的坐標(biāo)位置,這里就不多說了,下面主要的針對另外的兩個進(jìn)行簡單說明。

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.             if (getHeaderView(0).getVisibility() == GONE)
  9.                 getHeaderView(0).setVisibility(VISIBLE);
  10.             RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams();
  11.             params.width = RecyclerView.LayoutParams.MATCH_PARENT;
  12.             params.height = RecyclerView.LayoutParams.WRAP_CONTENT;
  13.             //使header隨moveY的值從頂部漸漸出現(xiàn)
  14.             if (moveY >= 400) {
  15.                 moveY = 100 + moveY / 4;
  16.             } else {
  17.                 moveY = moveY / 2;
  18.             }
  19.             viewHeight = getHeaderView(0).getHeight();
  20.             if (viewHeight <= 0)
  21.                 viewHeight = 130;
  22.             moveY = moveY - viewHeight;
  23.             params.setMargins(0, (int) moveY, 0, 0);
  24.             getHeaderView(0).setLayoutParams(params);
  25.             if (moveY > 80) {
  26.                 text.setText(getResources().getString(R.string.release_to_refresh));
  27.             } else {
  28.                 text.setText(getResources().getString(R.string.pull_to_refresh));
  29.             }
  30.         } else {
  31.             if (getHeaderView(0).getVisibility() != GONE && !isRefreshing) {
  32.                 getHeaderView(0).setVisibility(GONE);
  33.             }
  34.         }
  35.     }

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

ACTION_UP

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

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

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

下拉與上拉接口

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

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

狀態(tài)重置設(shè)置

在調(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.     public void setRefreshComplete() {
  11.         RecyclerView.LayoutParams params1 = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams();
  12.         params1.width = RecyclerView.LayoutParams.MATCH_PARENT;
  13.         params1.height = RecyclerView.LayoutParams.WRAP_CONTENT;
  14.         params1.setMargins(0, -getHeaderView(0).getHeight(), 0, 0);
  15.         getHeaderView(0).setLayoutParams(params1);
  16.         getHeaderView(0).setVisibility(GONE);
  17.         this.getAdapter().notifyDataSetChanged();
  18.         isRefreshing = false;
  19.     }

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

使用

xml中引用

 
 
  1.         android:id="@+id/recyclerView"
  2.         android:layout_width="match_parent"
  3.         android:layout_height="match_parent">

 設(shè)置監(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)絡(luò)數(shù)據(jù)完之后要在他們中調(diào)用相應(yīng)的mRecyclerView.setRefreshComplete()與 mRecyclerView.setLoadMoreComplete()來重置狀態(tài)。

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

總結(jié)

其實總的來說難點有兩個

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

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

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


網(wǎng)頁標(biāo)題:詳解RecyclerView下拉刷新與上拉更多
文章轉(zhuǎn)載:http://www.5511xx.com/article/cojhodo.html