Android PullToRefresh(下拉刷新)的使用詳解

開源項地址:https://github.com/chrisbanes/Android-PullToRefresh

在Android-PullToRefresh-master文件夾下,我們會看到還有三個文件夾:extras,
library,sample。其中sample就是作者爲我們提供的Demo,library是我們在使用Sample必須用到的jar。extras中是使用ListFragment和ViewPage用到的jar。

裏面有三個庫工程分別導入到eclipse中:



最主要的還是library庫工程

創建自己工程project,然後查看project的properties->android項,在下面添加依賴庫



然後就可以使用了

最基本的使用:

xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
    <com.handmark.pulltorefresh.library.PullToRefreshListView    
        android:id="@+id/pull_refresh_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
  
     />
    
</LinearLayout>

聲明瞭一個PullToRefreshListView,裏面所有的屬性都是ListView的,沒有任何其他屬性,當然了PullToRefreshListView也提供了很多配置的屬性,後面會詳細介紹。

package com.hust.mydemo;

import java.util.Arrays;
import java.util.LinkedList;

import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnLastItemVisibleListener;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
import com.handmark.pulltorefresh.library.PullToRefreshListView;

import android.R.integer;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.AndroidCharacter;
import android.text.format.DateUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;


public class MainActivity extends Activity {
    
	PullToRefreshListView mPullToRefreshListView;//下列刷新list
	ListView actualListView;
	LinkedList<String> listItems;//數據
	ArrayAdapter<String> adapter;//適配器
	
	private String[] mStrings = { 	
			"ListItem_00", "ListItem_01", "ListItem_02", "ListItem_03","ListItem_04",
			"ListItem_05", "ListItem_06", "ListItem_07", "ListItem_08","ListItem_09", 
			"ListItem_10", "ListItem_11", "ListItem_12", "ListItem_13", "ListItem_14", 
			"ListItem_15", "ListItem_16", "ListItem_17", "ListItem_18", "ListItem_19" };
	int i=0,j=20;
	
	/**刷新模式,
	 * 包括{
	 * 1.DISABLED(0x0)  			禁止通過手勢和手動執行
	 * 2.PULL_FROM_START(0x1)		可執行下拉刷新
	 * 3.PULL_FROM_END(0x2)			可執行上拉刷新
	 * 3.BOTH(0x3)					上下都可執行
	 * 4.MANUAL_REFRESH_ONLY(0x4)	禁止通過手勢執行,但可以手動設置
	 * }*/
	static final int MENU_SET_MODE = 2;
	
	/**這裏我們來判斷是下拉還是上拉*/
	private Mode CurrentMode;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
      /*  
       //監聽列表被刷新時事件
        mPullToRefreshListView.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);
				 // 更新顯示的label
				 mPullToRefreshListView.getLoadingLayoutProxy().setLastUpdatedLabel(label);
				
				 // 執行加載更多數據任務.
			    new GetDataTask().execute();
			}
		});*/
        
             
        
        mPullToRefreshListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {

			@Override
			public void onPullDownToRefresh(
					PullToRefreshBase<ListView> refreshView) {
				
				 //設置下拉時顯示的日期和時間
				 String label=DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(), 
						 DateUtils.FORMAT_SHOW_TIME|DateUtils.FORMAT_SHOW_DATE|DateUtils.FORMAT_ABBREV_ALL);
				 // 更新顯示的label
				 mPullToRefreshListView.getLoadingLayoutProxy().setLastUpdatedLabel(label);
				 CurrentMode=refreshView.getCurrentMode();
				 // 執行加載更多數據任務.
			    new GetDataTask().execute();
				
			}

			@Override
			public void onPullUpToRefresh(
					PullToRefreshBase<ListView> refreshView) {
								
				 //設置下拉時顯示的日期和時間
				 String label=DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(), 
						 DateUtils.FORMAT_SHOW_TIME|DateUtils.FORMAT_SHOW_DATE|DateUtils.FORMAT_ABBREV_ALL);
				 // 更新顯示的label
				 mPullToRefreshListView.getLoadingLayoutProxy().setLastUpdatedLabel(label);
				 CurrentMode=refreshView.getCurrentMode();
				 // 執行加載更多數據任務.
			    new GetDataTask().execute();
				
			}
		});
        
      //監聽滑動到底部的事件  
        mPullToRefreshListView.setOnLastItemVisibleListener(new OnLastItemVisibleListener() {

			@Override
			public void onLastItemVisible() {
				Toast.makeText(MainActivity.this,
						"已到列表底部!", Toast.LENGTH_SHORT).show();
				
			}
		});
        
    }
    public void initView(){
    	mPullToRefreshListView=(PullToRefreshListView) findViewById(R.id.pull_refresh_list);
    	//通過getRefreshableView()來得到一個listview對象
    	actualListView=mPullToRefreshListView.getRefreshableView();
    }
    /**
     * 設置listview的適配器
     */
    public void initData(){
    	listItems=new LinkedList<String>();
    	listItems.addAll(Arrays.asList(mStrings));
    	 //把string數組中的string添加到鏈表中
    	adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, listItems);
    	actualListView.setAdapter(adapter);
    }
    /**
     * @author:tuke
     * @tips  :通過異步任務來加載網絡中的數據,進行更新
     * 
     */
	private class GetDataTask extends AsyncTask<Void, Void, String[]> {

		@Override
		protected String[] doInBackground(Void... params) {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
			}
			return mStrings;
		}

		@Override
		protected void onPostExecute(String[] result) {
			//這裏是提供給我們比較MODE的方法,返回0則表示相當
			if (CurrentMode.compareTo(Mode.PULL_FROM_START)==0) {
				listItems.addFirst("ListItem_"+--i);
			}else {
				listItems.addLast("ListItem_"+(j++));
			}
			
					
			adapter.notifyDataSetChanged();

			//當數據加載完成,需要調用onRefreshComplete.
			mPullToRefreshListView.onRefreshComplete();

			super.onPostExecute(result);
		}
	}
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        switch (id) {
		case R.id.pullfromstart:
			mPullToRefreshListView.setMode(Mode.PULL_FROM_START);
			break;
       case R.id.pullfromend:
    	   mPullToRefreshListView.setMode(Mode.PULL_FROM_END);
			break;
       case R.id.both:
    	    mPullToRefreshListView.setMode(Mode.BOTH);
	        break;
		default:
			break;
		}  
        
               
        return super.onOptionsItemSelected(item);
    }
}
說白了,重要的地方就是設置模式,和設置監聽器,
1,設置Mode
Java代碼 收藏代碼
PullToRefreshListView mListView = (PullToRefreshListView) findViewById(R.id.list_view); 
mListView.setMode(Mode.BOTH); 
Mode.BOTH:同時支持上拉下拉
Mode.PULL_FROM_START:只支持下拉Pulling Down
Mode.PULL_FROM_END:只支持上拉Pulling Up


2,實現Listener
      如果Mode設置成Mode.BOTH,需要設置刷新Listener爲OnRefreshListener2,並實現onPullDownToRefresh()、onPullUpToRefresh()兩個方法。
     如果Mode設置成Mode.PULL_FROM_START或Mode.PULL_FROM_END,需要設置刷新Listener爲OnRefreshListener,同時實現onRefresh()方法。

     當然也可以設置爲OnRefreshListener2,但是Mode.PULL_FROM_START的時候只調用onPullDownToRefresh()方法,Mode.PULL_FROM的時候只調用onPullUpToRefresh()方法.



如果我們想改變下拉刷新的HeaderLayout的文字,文字顏色,背景,加載圖標怎麼辦?

1,在java代碼方法的設置:

可以在初始化完成mPullRefreshListView後,通過mPullRefreshListView.getLoadingLayoutProxy()可以得到一個ILoadingLayout對象,這個對象可以設置各種指示器中的樣式、文本等。


ILoadingLayout startLabels = mPullRefreshListView  
                .getLoadingLayoutProxy();  
        startLabels.setPullLabel("你可勁拉,拉...");// 剛下拉時,顯示的提示  
        startLabels.setRefreshingLabel("好嘞,正在刷新...");// 刷新時  
        startLabels.setReleaseLabel("你敢放,我就敢刷新...");// 下來達到一定距離時,顯示的提示

默認是上拉和下拉的字同時改變的,如果我希望單獨改變呢?

private void initIndicator()  
    {  
        ILoadingLayout startLabels = mPullRefreshListView  
                .getLoadingLayoutProxy(true, false);  
        startLabels.setPullLabel("你可勁拉,拉...");// 剛下拉時,顯示的提示  
        startLabels.setRefreshingLabel("好嘞,正在刷新...");// 刷新時  
        startLabels.setReleaseLabel("你敢放,我就敢刷新...");// 下來達到一定距離時,顯示的提示  
  
        ILoadingLayout endLabels = mPullRefreshListView.getLoadingLayoutProxy(  
                false, true);  
        endLabels.setPullLabel("你可勁拉,拉2...");// 剛下拉時,顯示的提示  
        endLabels.setRefreshingLabel("好嘞,正在刷新2...");// 刷新時  
        endLabels.setReleaseLabel("你敢放,我就敢刷新2...");// 下來達到一定距離時,顯示的提示  
    }  
mPullRefreshListView.getLoadingLayoutProxy(true, false);接收兩個參數,爲true,false返回設置下拉的ILoadingLayout;爲false,true返回設置上拉的。
   2,library類工程中爲pulltorefresh提供了很多自定義屬性



<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="PullToRefresh">

        <!-- A drawable to use as the background of the Refreshable View -->
        <!-- 設置刷新view的背景 -->
        <attr name="ptrRefreshableViewBackground" format="reference|color" />

        <!-- A drawable to use as the background of the Header and Footer Loading Views -->
        <!-- 設置頭部view的背景 -->
        <attr name="ptrHeaderBackground" format="reference|color" />

        <!-- Text Color of the Header and Footer Loading Views -->
        <!-- 設置頭部/底部文字的顏色 -->
        <attr name="ptrHeaderTextColor" format="reference|color" />

        <!-- Text Color of the Header and Footer Loading Views Sub Header -->
        <!-- 設置頭部/底部副標題的文字顏色 -->
        <attr name="ptrHeaderSubTextColor" format="reference|color" />

        <!-- Mode of Pull-to-Refresh that should be used -->
        <!-- 設置下拉刷新的模式,有多重方式可選。無刷新功能,從頂部刷新,從底部刷新,二者都有,只允許手動刷新 -->
        <attr name="ptrMode">
            <flag name="disabled" value="0x0" />
            <flag name="pullFromStart" value="0x1" />
            <flag name="pullFromEnd" value="0x2" />
            <flag name="both" value="0x3" />
            <flag name="manualOnly" value="0x4" />

            <!-- These last two are depreacted -->
            <!-- 這兩個屬性不推薦了,用上面的代替即可 -->
            <flag name="pullDownFromTop" value="0x1" />
            <flag name="pullUpFromBottom" value="0x2" />
        </attr>

        <!-- Whether the Indicator overlay(s) should be used -->
        <!-- 是否顯示指示箭頭 -->
        <attr name="ptrShowIndicator" format="reference|boolean" />

        <!-- Drawable to use as Loading Indicator. Changes both Header and Footer. -->
        <!-- 指示箭頭的圖片 -->
        <attr name="ptrDrawable" format="reference" />

        <!-- Drawable to use as Loading Indicator in the Header View. Overrides value set in ptrDrawable. -->
        <!-- 頂部指示箭頭的圖片,設置後會覆蓋ptrDrawable中頂部的設置 -->
        <attr name="ptrDrawableStart" format="reference" />

        <!-- Drawable to use as Loading Indicator in the Fooer View. Overrides value set in ptrDrawable. -->
        <!-- 底部指示箭頭的圖片,設置後會覆蓋ptrDrawable中底部的設置 -->
        <attr name="ptrDrawableEnd" format="reference" />

        <!-- Whether Android's built-in Over Scroll should be utilised for Pull-to-Refresh. -->
        <attr name="ptrOverScroll" format="reference|boolean" />

        <!-- Base text color, typeface, size, and style for Header and Footer Loading Views -->
        <!-- 設置文字的基本字體 -->
        <attr name="ptrHeaderTextAppearance" format="reference" />

        <!-- Base text color, typeface, size, and style for Header and Footer Loading Views Sub Header -->
        <!-- 設置副標題的基本字體 -->
        <attr name="ptrSubHeaderTextAppearance" format="reference" />

        <!-- Style of Animation should be used displayed when pulling. -->
        <!-- 設置下拉時標識圖的動畫,默認爲rotate -->
        <attr name="ptrAnimationStyle">
            <flag name="rotate" value="0x0" />
            <flag name="flip" value="0x1" />
        </attr>

        <!-- Whether the user can scroll while the View is Refreshing -->
        <!-- 設置刷新時是否允許滾動,一般爲true -->
        <attr name="ptrScrollingWhileRefreshingEnabled" format="reference|boolean" />

        <!--
            Whether PullToRefreshListView has it's extras enabled. This allows the user to be 
            able to scroll while refreshing, and behaves better. It acheives this by adding
            Header and/or Footer Views to the ListView.
        -->
        <!-- 允許在listview中添加頭/尾視圖 -->
        <attr name="ptrListViewExtrasEnabled" format="reference|boolean" />

        <!--
            Whether the Drawable should be continually rotated as you pull. This only
            takes effect when using the 'Rotate' Animation Style.
        -->
        <!-- 當設置rotate時,可以用這個來設置刷新時旋轉的圖片 -->
        <attr name="ptrRotateDrawableWhilePulling" format="reference|boolean" />

        <!-- BELOW HERE ARE DEPRECEATED. DO NOT USE. -->
        <attr name="ptrAdapterViewBackground" format="reference|color" />
        <attr name="ptrDrawableTop" format="reference" />
        <attr name="ptrDrawableBottom" format="reference" />
    </declare-styleable>

</resources>

ptrMode,ptrDrawable,ptrAnimationStyle這三個上面已經介紹過。
ptrRefreshableViewBackground 設置整個mPullRefreshListView的背景色
ptrHeaderBackground 設置下拉Header或者上拉Footer的背景色
ptrHeaderTextColor 用於設置Header與Footer中文本的顏色
ptrHeaderSubTextColor 用於設置Header與Footer中上次刷新時間的顏色
ptrShowIndicator如果爲true會在mPullRefreshListView中出現icon,右上角和右下角,挺有意思的。
ptrHeaderTextAppearance , ptrSubHeaderTextAppearance分別設置拉Header或者上拉Footer中字體的類型顏色等等。
ptrRotateDrawableWhilePulling當動畫設置爲rotate時,下拉是是否旋轉。

看到有這麼多可以設置的屬性,別以爲真的就可以定製了。真正要定製還得到layout中改變刷新佈局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
    <com.handmark.pulltorefresh.library.PullToRefreshListView
         xmlns:ptr="http://schemas.android.com/apk/res-auto"  
        android:id="@+id/pull_refresh_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        ptr:ptrAnimationStyle="rotate"
        ptr:ptrHeaderTextColor="#000000"
        ptr:ptrHeaderSubTextColor="#00ffff"
        ptr:ptrHeaderBackground="@null"
        ptr:ptrDrawable="@drawable/android"  
        ptr:ptrMode="both"
     />
    
</LinearLayout>






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章