1. 程式人生 > >android:ListView下拉重新整理上拉載入更多(PullToRefresh框架抽取)

android:ListView下拉重新整理上拉載入更多(PullToRefresh框架抽取)

大家不難發現當你使用SwipeRefreshLayout下拉的時候佈局檔案不會跟著手勢往下滑,而且想要更改這個缺陷好像非常不容易。

雖然SwipeRefreshLayout非常簡單易懂,但是需求需要下拉重新整理的時候跟著手勢下滑就不能用SwipeRefreshLayout了;

上面圖片效果使用的是PullToRefresh框架,在我的工程裡面沒有匯入類庫和jar包,而是把下拉重新整理功能直接抽取出來使用;

當下拉的時候回撥監聽,在抽取完下拉重新整理功能的基礎上實現上拉載入更多功能實現也非常簡單,所以順手寫上了;

我是從github上下載的Android-PullToRefresh-master框架,在library中抽取的;

首先需要複製的類大概有十個左右:


然後跟進報錯檢視需要什麼檔案就複製什麼檔案;把錯誤搞定之後首先來看下佈局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- 我們添加了一個屬性:ptr:ptrMode="both" ,意思:上拉和下拉都支援。
		可選值為:disabled(禁用下拉重新整理),pullFromStart(僅支援下拉重新整理),
		pullFromEnd(僅支援上拉重新整理),both(二者都支援),manualOnly(只允許手動觸發) -->
	<!-- 
		ptr:ptrAnimationStyle="rotate"
		FlipLoadingLayout為iOS風格的箭頭顛倒的重新整理動畫
		ptr:ptrAnimationStyle="flip"
		RotateLoadingLayout為android風格的圖片旋轉動畫 -->
    <com.ptrflv.www.pulltorefreshlistview.PullToRefreshListView
        xmlns:ptr="http://schemas.android.com/apk/res-auto" 
        android:id="@+id/pull_to_refresh_listview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        ptr:ptrMode="both"
        ptr:ptrAnimationStyle="flip"
         />

</LinearLayout>

值得注意的是預設情況下下拉重新整理的執行動畫中顯示的文字是英文,這裡我們需要手動修改pull_refresh_strings.xml中的內容:
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- 上拉重新整理 -->
    <!-- …代表三個點   ... -->
    <string name="pull_to_refresh_pull_label">向下拉重新整理…</string>
    <string name="pull_to_refresh_release_label">鬆開更新…</string>
    <string name="pull_to_refresh_refreshing_label">正在載入…</string>

    <!-- 下拉載入更多 -->
    <string name="pull_to_refresh_from_bottom_pull_label">向下拉載入更多…</string>
    <string name="pull_to_refresh_from_bottom_release_label">鬆開載入更多…</string>
    <string name="pull_to_refresh_from_bottom_refreshing_label">正在載入…</string>

</resources>

下面是呼叫下拉重新整理和上下載入更多的程式碼:
public class MainActivity extends Activity {

	private PullToRefreshListView pullToRefreshListView;
	//adapter的資料來源
	private List<String> numList=new ArrayList<String>();
	private ArrayAdapter<String> arrayAdapter; 
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		pullToRefreshListView=(PullToRefreshListView) findViewById(R.id.pull_to_refresh_listview);
		//初始化資料
		for(int x=0;x<18;x++){
			numList.add(""+x);
		}
		
		arrayAdapter = new ArrayAdapter<String>(this, R.layout.item_listview,R.id.textview,numList);
		pullToRefreshListView.setAdapter(arrayAdapter);
		
		//設定重新整理監聽 
		pullToRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {

			@Override
			public void onRefresh(PullToRefreshBase<ListView> refreshView) {
				 
				String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),  
                         DateUtils.FORMAT_SHOW_TIME  | DateUtils.FORMAT_SHOW_DATE  | DateUtils.FORMAT_ABBREV_ALL);  
				 
                 // 顯示最後更新的時間  
                 refreshView.getLoadingLayoutProxy() .setLastUpdatedLabel(label);
                 
                 //代表下拉重新整理
                 if(refreshView.getHeaderLayout().isShown()){
                	 
                	 new Thread(){
                		 public void run() {
                			 try {
                				 sleep(1000);
                				 
                				 handler.sendEmptyMessage(99);
                				 
                			 } catch (InterruptedException e) {
                				 e.printStackTrace();
                			 }
                		 };
                	 }.start();
                 }
                 
                 //代表下拉重新整理
                 if(refreshView.getFooterLayout().isShown()){
                	 new Thread(){
                		 public void run() {
                			 try {
                				 sleep(1000);
                				 
                				 handler.sendEmptyMessage(98);
                				 
                			 } catch (InterruptedException e) {
                				 e.printStackTrace();
                			 }
                		 };
                	 }.start();
                 }
				
			}
		});
		
	}
	
	private Handler handler=new Handler(){
		public void handleMessage(android.os.Message msg) {
			
			if(msg.what==99){
				numList.add(0, "英雄聯盟");
				arrayAdapter.notifyDataSetChanged();
				//關閉重新整理的動畫
				pullToRefreshListView.onRefreshComplete(); 
			}
			
			if(msg.what==98){
				numList.add(numList.size(), "魔獸世界");
				arrayAdapter.notifyDataSetChanged();
				//關閉重新整理的動畫
				pullToRefreshListView.onRefreshComplete(); 
			}
			
		};
	};

}

在判斷上拉重新整理和下拉載入的時候

refreshView.getFooterLayout().isShown()

refreshView.getHeaderLayout().isShown()會報錯,因為PullToRefreshBase這兩個方法預設不是共有方法,我們需要手動該更為public

原始碼下載