前言java
之前在實現ListView下拉刷新和上拉加載數據的時候都是去繼承原生的ListView重寫它的一些方法,實現起來很是繁雜,須要咱們本身去給ListView定製下拉刷新和上拉加載的佈局文件,而後添加ScrollView和OnTouch監聽,設置回調接口獲取數據,爲了更好的交互體驗,咱們還不能直接利用setVisibility隱藏顯示佈局等等一大堆的操做,累都累死了。(題外話:關於下拉刷新在新版的android-support-v4.jar裏,其實谷歌已經爲咱們提供了一個控件叫SwipeRefreshLayout,使用方法也很是簡單,有興趣的朋友能夠本身網上了解下)它的實現效果大體是這樣的:react
今天來講下關於開源項目PullToRefresh的使用方法,輕輕鬆鬆幾行代碼就能夠把下拉刷新和上拉加載功能給實現了。(開源的東西雖然好用,但做爲學習,仍是建議你們先不用開源組件本身去實現一遍所須要的效果,畢竟原理須要懂),好了,言歸正傳,我儘可能的言簡意賅,進入主題。android
先看下最後的實現效果圖:git
準備工做github
一、既然是利用PullToRefresh組件來實現下拉刷新和上拉加載數據的效果,那麼首先咱們須要先把它下載下來。app
這是PullToRefresh在GitHub上的下載地址:https://github.com/chrisbanes/Android-PullToRefresh/wiki/Quick-Start-Guideide
很簡單,下載完畢後咱們就能夠開始進入開發工做了。佈局
磨刀不誤砍柴工學習
一、首先先導入該項目字體
在導入項目後,咱們會發現出現了不少紅叉,不用擔憂,這個只是引用庫路徑出錯罷了,咱們右鍵點擊有紅叉的文件選擇Properties,選擇Andorid下拉,把對應的library從新 引入便可,依樣畫葫蘆,其餘出現的紅叉的文件也都這樣作。
把紅叉都解決完以後,有個很重要的事情要作,把剛導入的全部文件夾裏的android-support-v4.jar和你本身的項目裏的v4包統一了,避免v4包版本不一致致使項目運行出錯。
幹活幹活!
佈局文件,很是簡單,只放了一個可下拉刷新的ListView
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 6 <com.handmark.pulltorefresh.library.PullToRefreshListView 7 android:id="@+id/mylistview" 8 android:layout_width="match_parent" 9 android:layout_height="match_parent" 10 > 11 </com.handmark.pulltorefresh.library.PullToRefreshListView> 12 13 </RelativeLayout>
主代碼文件:
1 package com.rabbit.pulltorefreshdemo; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import android.app.Activity; 7 import android.os.AsyncTask; 8 import android.os.Bundle; 9 import android.widget.ArrayAdapter; 10 import android.widget.ListView; 11 12 import com.handmark.pulltorefresh.library.PullToRefreshBase; 13 import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; 14 import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener; 15 import com.handmark.pulltorefresh.library.PullToRefreshListView; 16 17 public class MainActivity extends Activity { 18 19 //聲明下拉刷新ListView組件 20 private PullToRefreshListView myListView; 21 //聲明數據源 22 private List<String> data; 23 //聲明適配器 24 private ArrayAdapter<String> adapter; 25 26 @Override 27 protected void onCreate(Bundle savedInstanceState) { 28 super.onCreate(savedInstanceState); 29 setContentView(R.layout.activity_main); 30 //獲取下拉刷新ListView組件 31 this.myListView=(PullToRefreshListView) findViewById(R.id.mylistview); 32 //模擬數據 33 this.data=new ArrayList<String>(); 34 data.add("JAVA"); 35 data.add("PHP"); 36 data.add("C++"); 37 data.add("C#"); 38 //實例化Adapter 39 this.adapter=new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, data); 40 //設置Adapter 41 myListView.setAdapter(adapter); 42 //設置支持上下拉動和監聽 43 myListView.setMode(Mode.BOTH); 44 myListView.setOnRefreshListener(new OnRefreshListener<ListView>() { 45 46 @Override 47 public void onRefresh(PullToRefreshBase<ListView> refreshView) { 48 49 if(refreshView.isShownHeader()){ 50 //判斷頭佈局是否可見,若是可見執行下拉刷新 51 //設置尾佈局樣式文字 52 myListView.getLoadingLayoutProxy().setRefreshingLabel("正在刷新"); 53 myListView.getLoadingLayoutProxy().setPullLabel("下拉刷新數據"); 54 myListView.getLoadingLayoutProxy().setReleaseLabel("釋放開始刷新"); 55 //模擬加載數據線程休息3秒 56 new AsyncTask<Void, Void, Void>() { 57 @Override 58 protected Void doInBackground(Void... params) { 59 try { 60 Thread.sleep(3000); 61 data.add("刷新數據1"); 62 data.add("刷新數據2"); 63 data.add("刷新數據3"); 64 } catch (InterruptedException e) { 65 e.printStackTrace(); 66 } 67 return null; 68 } 69 70 @Override 71 protected void onPostExecute(Void result) { 72 super.onPostExecute(result); 73 //完成對下拉刷新ListView的更新操做 74 adapter.notifyDataSetChanged(); 75 //將下拉視圖收起 76 myListView.onRefreshComplete(); 77 } 78 }.execute(); 79 } 80 if(refreshView.isShownFooter()){ 81 //判斷尾佈局是否可見,若是可見執行上拉加載更多 82 //設置尾佈局樣式文字 83 myListView.getLoadingLayoutProxy().setRefreshingLabel("正在加載"); 84 myListView.getLoadingLayoutProxy().setPullLabel("上拉加載更多"); 85 myListView.getLoadingLayoutProxy().setReleaseLabel("釋放開始加載"); 86 //模擬加載數據線程休息3秒 87 new AsyncTask<Void, Void, Void>() { 88 @Override 89 protected Void doInBackground(Void... params) { 90 try { 91 Thread.sleep(3000); 92 data.add("更多數據1"); 93 data.add("更多數據2"); 94 data.add("更多數據3"); 95 } catch (InterruptedException e) { 96 e.printStackTrace(); 97 } 98 return null; 99 } 100 101 @Override 102 protected void onPostExecute(Void result) { 103 super.onPostExecute(result); 104 //完成對下拉刷新ListView的更新操做 105 adapter.notifyDataSetChanged(); 106 //將下拉視圖收起 107 myListView.onRefreshComplete(); 108 } 109 }.execute(); 110 111 112 } 113 114 } 115 }); 116 117 } 118 119 120 }
其實和普通ListView的使用方式差很少,只是多了一些屬性的設置,這裏有幾個要注意的地方:
一、模式的設置,默認下PullToRefresh的刷新模式只支持下拉刷新,咱們能夠經過setMode(Mode.XXXX)來設置它
1 BOTH:上拉刷新和下拉刷新都支持 2 DISABLED:禁用上拉下拉刷新 3 PULL_FROM_START:僅支持下拉刷新(默認) 4 PULL_FROM_END:僅支持上拉刷新 5 MANUAL_REFRESH_ONLY:只容許手動觸發
二、補充上述描述第1點,當咱們設置模式爲BOTH的時候,咱們就能夠實現下拉和上拉了,但這裏的它們的樣式是同樣的,咱們須要的場景應該是下拉的時候顯示"下拉刷新數據,正在刷新數據,數據刷新成功....",而在咱們上拉的時候應該出現的場景是"上拉加載數據,正在加載數據,加載數據成功...",因此這裏咱們須要對樣式進行設置。
因爲PullToRefresh默認是沒給咱們判斷究竟是上拉仍是下拉的方法,因此咱們須要去源代碼裏修改下它的代碼,Ctrl+Shift+T搜索下PullToRefreshBase類,打開後再後最後面咱們補上這樣一段代碼,咱們能夠根據當頭佈局可見的時候執行下拉刷新,當尾佈局可見的時候執行下拉加載,這樣咱們就能夠根據頭尾佈局來判斷用戶究竟是執行上拉仍是下拉操做了。
1 //判別頭部是否展現出來,若是展現出來表明下拉使得頭部展現。true爲下拉 2 public boolean isShownHeader() { 3 return getHeaderLayout().isShown(); 4 } 5 //判別低部是否展現出來,若是展現出來表明上拉使得低部展現。true爲上拉 6 public boolean isShownFooter() { 7 return getFooterLayout().isShown(); 8 }
三、這是關於PullToRefresh的一些屬性設置,在源碼中能夠找到,這裏我作了下翻譯:
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 <declare-styleable name="PullToRefresh"> 4 <!-- A drawable to use as the background of the Refreshable View --> 5 <!-- 設置整個刷新列表的背景色 --> 6 <attr name="ptrRefreshableViewBackground" format="reference|color" /> 7 <!-- A drawable to use as the background of the Header and Footer Loading Views --> 8 <!-- 設置下拉Header或者上拉Footer的背景色 --> 9 <attr name="ptrHeaderBackground" format="reference|color" /> 10 <!-- Text Color of the Header and Footer Loading Views --> 11 <!-- 用於設置Header與Footer中文本的顏色 --> 12 <attr name="ptrHeaderTextColor" format="reference|color" /> 13 <!-- Text Color of the Header and Footer Loading Views Sub Header --> 14 <!-- 用於設置Header與Footer中上次刷新時間的顏色 --> 15 <attr name="ptrHeaderSubTextColor" format="reference|color" /> 16 <!-- Mode of Pull-to-Refresh that should be used --> 17 <attr name="ptrMode"> 18 <flag name="disabled" value="0x0" /><!-- 禁用下拉刷新 --> 19 <flag name="pullFromStart" value="0x1" /><!-- 僅支持下拉刷新 --> 20 <flag name="pullFromEnd" value="0x2" /><!-- 僅支持上拉刷新 --> 21 <flag name="both" value="0x3" /><!-- 上拉刷新和下拉刷新都支持 --> 22 <flag name="manualOnly" value="0x4" /><!-- 只容許手動觸發 --> 23 24 <!-- These last two are depreacted --> 25 <flag name="pullDownFromTop" value="0x1" /> 26 <flag name="pullUpFromBottom" value="0x2" /> 27 </attr> 28 <!-- Whether the Indicator overlay(s) should be used --> 29 <!-- 若是爲true會在mPullRefreshListView中出現icon,右上角和右下角,挺有意思的 --> 30 <attr name="ptrShowIndicator" format="reference|boolean" /> 31 <!-- Drawable to use as Loading Indicator. Changes both Header and Footer. --> 32 <!-- 同時改變頭部和底部的圖標 --> 33 <attr name="ptrDrawable" format="reference" /> 34 <!-- Drawable to use as Loading Indicator in the Header View. Overrides value set in ptrDrawable. --> 35 <!-- 頭部視圖的圖標--> 36 <attr name="ptrDrawableStart" format="reference" /> 37 38 <!-- Drawable to use as Loading Indicator in the Footer View. Overrides value set in ptrDrawable. --> 39 <!-- 底部視圖的圖標 --> 40 <attr name="ptrDrawableEnd" format="reference" /> 41 <!-- Whether Android's built-in Over Scroll should be utilised for Pull-to-Refresh. --> 42 <attr name="ptrOverScroll" format="reference|boolean" /> 43 <!-- Base text color, typeface, size, and style for Header and Footer Loading Views --> 44 <!-- 分別設置拉Header或者上拉Footer中字體的類型顏色等等 --> 45 <attr name="ptrHeaderTextAppearance" format="reference" /> 46 <!-- Base text color, typeface, size, and style for Header and Footer Loading Views Sub Header --> 47 <attr name="ptrSubHeaderTextAppearance" format="reference" /> 48 <!-- Style of Animation should be used displayed when pulling. --> 49 <attr name="ptrAnimationStyle"> 50 <flag name="rotate" value="0x0" /><!-- flip(翻轉動畫), rotate(旋轉動畫) --> 51 <flag name="flip" value="0x1" /> 52 </attr> 53 <!-- Whether the user can scroll while the View is Refreshing --> 54 <!-- 刷新的時候,是否容許ListView或GridView滾動 --> 55 <attr name="ptrScrollingWhileRefreshingEnabled" format="reference|boolean" /> 56 <!-- 57 Whether PullToRefreshListView has it's extras enabled. This allows the user to be 58 able to scroll while refreshing, and behaves better. It acheives this by adding 59 Header and/or Footer Views to the ListView. 60 --> 61 <!-- 決定了Header,Footer以何種方式加入mPullRefreshListView,true爲headView方式加入,就是滾動時刷新頭部會一塊兒滾動 --> 62 <attr name="ptrListViewExtrasEnabled" format="reference|boolean" /> 63 <!-- 64 Whether the Drawable should be continually rotated as you pull. This only 65 takes effect when using the 'Rotate' Animation Style. 66 --> 67 <attr name="ptrRotateDrawableWhilePulling" format="reference|boolean" /> 68 <!-- BELOW HERE ARE DEPRECEATED. DO NOT USE. --> 69 <attr name="ptrAdapterViewBackground" format="reference|color" /> 70 <attr name="ptrDrawableTop" format="reference" /> 71 <attr name="ptrDrawableBottom" format="reference" /> 72 </declare-styleable> 73 </resources>
設置屬性也很簡單,在對應的佈局文件裏直接設置就能夠,好比字體顏色:
1 <com.handmark.pulltorefresh.library.PullToRefreshListView 2 xmlns:ptr="http://schemas.android.com/apk/res-auto" 3 android:id="@+id/lv_friendsline" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 ptr:ptrHeaderTextColor="#000000" 7 >
其餘的一些,你們看我代碼註釋吧,寫的很是詳細了。
補充:關於這個PullToRefresh它不只僅支持ListView,好比ScrollView,GridView等等,只要是能滾動到控件它都通吃,具體使用方法你們能夠參考咱們一開始導入的項目裏的LauncherActivity。
做者:Balla_兔子
出處:http://www.cnblogs.com/lichenwei/本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。正在看本人博客的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,往後必有一番做爲!旁邊有「推薦」二字,你就順手把它點了吧,相得準,我分文不收;相不許,你也好回來找我!