Android-PullToRefresh 使用心得


目前下拉刷新已經滿大街都是,在自己的應用如果不使用這個模式的話,出門都不好意思和人家打招呼,該文章就是簡單探討下針對於 github 上的這個開源項目的使用心得。

為什么是它?因為在 stackoverflow 上大家都說它不錯,所以就試試看吧!該項目的位置 Android-PullToRefresh 遺憾的是目前已經停止維護,但是已經足夠強大所以不維護就不維護吧!

注意:對應的還有一個項目,也是這個作者剛剛開的 ActionBar-PullToRefresh 這個是在 actionbar 上增加下拉的效果,Android-PullToRefresh 這個工程在我們下拉的時候會有一個 view 顯示出來,而這個工程直接就是利用 actionbar 來顯示,注意這兩者的區別

首先,看看目前幾個主流 app 的下拉刷新的效果。

sina 微博

 


網易新聞

 

騰訊微博

 

接下來,是我們自己實現后的效果

 

 

從圖片來看非常的相似,所以接下來我們就看看這個開源的 lib 如何使用。

源碼下載下來之后將 library 這個目錄中的代碼放到一個位置,然后在主工程中去引用它,通常都是在主工程的 project.properties 中去指定引用的位置

android.library.reference.4=library/Android-PullToRefresh  

因為這個是我工程中加入的第四個引用的庫,所以是 reference.4,如果這是你的第一個的話,那么應該是 reference.1,這個關於庫的引用在 android sdk 的 samples 目錄下可以找到了兩個工程 "TicTacToeLib" 和 "TicTacToeMain" 來自己參考下。

好了,先 build 下Android-PullToRefresh 生成 jar 包,然后在 build 主工程,應該沒什么問題,繼續。

接下來就關於這個部分的使用,使用主要考慮兩個方法:1. 這個 lib 的基本功能的使用,2. 這個 lib 的自定義擴展

基本功能的使用

1. 在 layout 文件中對應的 listview 不能使用 android 原生的 listview,而是要使用 PullToRefreshListView 代碼如下

<?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/my_list"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:cacheColorHint="#00000000"  
        android:fadingEdge="none"  
        android:fastScrollEnabled="false"  
        android:footerDividersEnabled="false"  
        android:headerDividersEnabled="false"  
        android:smoothScrollbar="true"  
        ptr:ptrAnimationStyle="flip"  
        ptr:ptrHeaderTextAppearance="@android:attr/textAppearanceMedium"/>  
  
    <!-- Here is the view to show if the list is emtpy -->  
    <ScrollView android:id="@+id/empty"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:fillViewport="true">  
  
        <LinearLayout  
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:orientation="vertical">  
  
            <TextView  
                android:id="@+id/emptyText"  
                android:layout_width="fill_parent"  
                android:layout_height="fill_parent"  
                android:text="@string/noText"  
                android:textSize="20sp"  
                android:textColor="?android:attr/textColorSecondary"  
                android:paddingLeft="10dip"  
                android:paddingRight="10dip"  
                android:paddingTop="10dip"  
                android:lineSpacingMultiplier="0.92"  
                android:gravity="center" />  
        </LinearLayout>  
    </ScrollView>  
</LinearLayout>  

在這個 layout 中分為上下兩個部分,上面是一個 listview, 下面是一個 empty view,用來在沒有內容的時候顯示,通過 listview 的 setEmptyView()就可以達到這個效果,千萬不要自己費事去寫兩個 view 的邏輯控制代碼。

關於 ptr:XXX 屬性的使用,會在自定義擴展的那個部分解釋下,這里暫時跳過。

2. 在代碼中使用這個 listview,代碼如下

private PullToRefreshListView mList;  
  
@Override  
protected void onCreate(Bundle savedInstanceState) {  
    // ...  
  
    mList = (PullToRefreshListView)findViewById(R.id.my_list);  
    mList.setEmptyView(findViewById(R.id.empty));  
    mList.setOnItemClickListener(new OnItemClickListener() {  
  
        @Override  
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
            if (DEBUG) Log.d(TAG, "onItemClick() : pos=" + position + ", id=" + id);  
            parent.getAdapter().getItem(position);  // @warning: Should not use mAdapter  
              
            // do something  
        }  
  
    });  
  
    mList.setOnPullEventListener(new OnPullEventListener<ListView>() {  
  
        @Override  
        public void onPullEvent(PullToRefreshBase<ListView> refreshView, State state,  
                Mode direction) {  
            if (DEBUG) Log.d(TAG, "onPullEvent() : " + state.name());  
  
            if (state.equals(State.PULL_TO_REFRESH)) {  
                refreshView.getLoadingLayoutProxy().setPullLabel(getString(R.string.pull_to_refresh));  
                refreshView.getLoadingLayoutProxy().setReleaseLabel(getString(R.string.release_to_refresh));  
                refreshView.getLoadingLayoutProxy().setRefreshingLabel(getString(R.string.loading));  
  
                String label = DateUtils.formatDateTime(getApplicationContext(),  
                        System.currentTimeMillis(),  
                        DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);  
                // Update the LastUpdatedLabel  
                refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(  
                        getString(R.string.updated) + " : " + label);  
            }  
        }  
    });  
  
    mList.setOnRefreshListener(new OnRefreshListener<ListView>() {  
        @Override  
        public void onRefresh(PullToRefreshBase<ListView> refreshView) {  
            if (DEBUG) Log.d(TAG, "onRefresh()");  
  
            // Do work to refresh the list here.  
            refresh();  
        }  
    });  
  
    // ...  
}  

此處有幾個地方要注意:
1. 如果想對 list item 點擊之后做一些事情,此處有個問題要注意下,那就是我們的下來顯示的 view 是 header view,所以此處在 onItemClick() 函數中傳入的 position 不是從 0 開始而是從 1 開始,如果我們使用通常情況下的 mAdapter 去 getItem() 則實際中始終獲取的都是我們點擊 item 的下一個 item 的位置,所以此處我們要通過傳進來的 parent 的 adapter 來獲取 item,詳細可以參考當ListView有Header時,onItemClick里的position不正確

 

2. 因為下拉的時候顯示的文字,每個人有每個的需求,所以會不一樣,所以就需要使用 setOnPullEventListener() 來更新文字,這個開源庫自己提供的 sample 中更新文字是放到 setOnRefreshListener() 中,但是那個只是在刷新的時候才更新問題,通過對比那些常用 app 的下拉效果你會發現那個時候在更新已經慢了,所以要放到這里

3. 此處代碼沒有列出來,就是 refresh 完了之后要把 pull view hide 起來,調用 onRefreshComplete() 即可,詳情可以參考它自己提供的 sample。

4. 還要注意的是,還有很大的需求是點擊刷新,那么點擊之后這個 pull view 也要 show 出來,但是不應該 show "下拉可以刷新" 和 "松開可以刷新" 這兩個畫面,而是直接顯示正在刷新的那個畫面,這要怎么做到的呢?通過setRefreshing()這個函數即可做到,對應有另外一個函數叫做demo() 它包括了 “下拉->松開->刷新” 的整個過程,這是我們在這種條件下不需要的。

5. 在它自己的 sample 中還可以增加聲音的效果,這個比較簡單,自己看下即可。

Android-PullToRefresh 自定義擴展

此處的擴展指的是不修改這個開源庫任何一行本身的代碼來實現自定義一些屬性,那些屬性可以自定義這個可以在這個庫的 values/attrs.xml 中看到,我們使用的時候就像上面 layout 中的寫法一樣,首先包含下命名空間,然后就可以指定對應的屬性

<com.handmark.pulltorefresh.library.PullToRefreshListView  
        xmlns:ptr="http://schemas.android.com/apk/res-auto"  
        android:id="@+id/my_list"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:cacheColorHint="#00000000"  
        android:fadingEdge="none"  
        android:fastScrollEnabled="false"  
        android:footerDividersEnabled="false"  
        android:headerDividersEnabled="false"  
        android:smoothScrollbar="true"  
        ptr:ptrAnimationStyle="flip"  
        ptr:ptrHeaderTextAppearance="@android:attr/textAppearanceMedium"/>  

"xmlns:ptr="http://schemas.android.com/apk/res-auto" 聲明下,然后可以使用 ptr:XXX 的屬性了。

一些屬性的簡單說明

ptrAnimationStyle :  flip 這個效果是有向下和向上的兩個箭頭的,rotate 沒有箭頭不管怎么拉都是一個 progress bar

ptrMode :both 指的是 listview 的上面和下面都有這種拉動刷新的效果,下面的刷新通常我們在滑到最下面然后 loading 數據的時候可以看到

其他的屬性可以在 attrs.xml 中看它的注釋來理解,總之一句話,盡量少自己造輪子先看看作者有沒有提供接口。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM