PullToRefresh使用详解

原文地址:http://blog.csdn.net/harvic880925/article/details/17680305

原文地址:http://blog.csdn.net/ueryueryuery/article/details/17440465


使用PullToRefresh实现下拉刷新和上拉加载

PullToRefresh是一套实现非常好的下拉刷新库,它支持:

1.ListView

2.ExpandableListView

3.GridView

4.WebView

等多种常用的需要刷新的View类型,而且使用起来也十分方便。

(下载地址:https://github.com/chrisbanes/Android-PullToRefresh)


下载完成,将它导入到eclipse中,作为一个library导入到你的工程中就好了。


一、废话少说,下拉刷新go。

 1.在你的布局文件中加上你想用的View就好了,比如这儿我想用一个支持下拉 刷新的ExpandableListView

[html]  view plain copy
  1. <com.handmark.pulltorefresh.library.PullToRefreshExpandableListView  
  2.     android:id="@+id/expand_list"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" />  

2. 在你的Activity代码中进行简单的设置:

[java]  view plain copy
  1. mExpandList = (PullToRefreshExpandableListView) rootView.findViewById(R.id.expand_list);  
  2. mExpandList.getRefreshableView().setGroupIndicator(null);  
  3. mExpandList.getRefreshableView().setDivider(null);  
  4. mExpandList.getRefreshableView().setSelector(android.R.color.transparent);  
  5. mExpandList.getRefreshableView().setOnGroupClickListener(this);  
  6. mExpandList.setOnRefreshListener(this);  

第一行是找到这个View,最后一行是为它加上刷新的监听器,中间的几行是我对ExpandableListView进行一些设置。

这样其实就已经可以下拉刷新了,但刷新时需要运行的代码写在哪呢,还有为什么下拉不会收起来呢,且往下看。


3.下拉刷新时执行的方法onRefresh()

[java]  view plain copy
  1. @Override  
  2. public void onRefresh(PullToRefreshBase<ExpandableListView> refreshView) {  
  3.     if (!isRefreshing) {  
  4.         isRefreshing = true;  
  5.         updateList(true);  
  6.     } else {  
  7.         mExpandList.onRefreshComplete();  
  8.     }  
  9. }  

一般来说我们会开另一个线程去获取数据,所以这儿会加上一个判断,如果已经在获取数据了,就onRefreshComplete(),就是将下拉收起;否则就去开新线程取数据,取完记得也要onRefreshComplete()哦!


二、上拉加载

如果你不想再费时间去自己写一个上拉加载,不妨试一下PullToRefresh自带的上拉效果哦!

PullToRefresh本身支持下拉刷新和上拉刷新,所以我们只需要将上拉刷新改成上拉加载就行了。


1.设置Mode

[java]  view plain copy
  1. // set mode to BOTH  
  2. mExpandList.setMode(Mode.BOTH);  
  3. mExpandList.getLoadingLayoutProxy(falsetrue).setPullLabel(getString(R.string.pull_to_load));  
  4. mExpandList.getLoadingLayoutProxy(falsetrue).setRefreshingLabel(getString(R.string.loading));  
  5. mExpandList.getLoadingLayoutProxy(falsetrue).setReleaseLabel(getString(R.string.release_to_load));  

Mode设置为Mode.BOTH后,下拉和上拉都会执行onRefresh()中的方法了。

因为界面上边,我们要显示“下拉刷新”,下边我们要显示“上拉加载”,所以后三行就是改变下边部分的文字,getLoadingLayoutProxy(false, true)方法大家可以自己感受一下。


2.怎么区分下拉/上拉

网上有的同学是用onScrollListener来判断,这样并不严谨,我依靠是header还是footer处于可见状态来区分下拉和上拉,如果是下拉,那header一定是可见的;反之,footer一定是可见的。

但是PullToRefreshExpandableListView并没有提供这样的接口,那我们就来小改一下我们引入的工程吧,很简单:

找到包“com.handmark.pulltorefresh.library”下的PullToRefreshAdapterViewBase.java这个类,加入两个新接口:

[java]  view plain copy
  1. public boolean isHeaderShown() {  
  2.     return getHeaderLayout().isShown();  
  3. }  
  4.   
  5. public boolean isFooterShown() {  
  6.     return getFooterLayout().isShown();  
  7. }  

这样就行了哦,重新编译一下这个工程,和你自己的工程。


在onRefresh()中这样来用:

[java]  view plain copy
  1. @Override  
  2. public void onRefresh(PullToRefreshBase<ExpandableListView> refreshView) {  
  3.     if (!isRefreshing) {  
  4.         isRefreshing = true;  
  5.         if (mExpandList.isHeaderShown()) {  
  6.             Utils.LOGD("pull-to-refresh");  
  7.             refreshOnlineStatus(true);  
  8.         } else if (mExpandList.isFooterShown()) {  
  9.             Utils.LOGD("pull-to-load-more");  
  10.             loadNextPage();  
  11.         }  
  12.     } else {  
  13.         mExpandList.onRefreshComplete();  
  14.     }  
  15. }  


很简单吧,这样我们就YD地使用PullToRefresh实现了下拉刷新和上拉加载,LOL,希望多多少少能帮到大家。


=================================================================

更新于2014-07-01

近来发现:

1.实现上拉监听,只需要实现OnRefreshListener2就可以了,同时别忘记setMode(Mode.BOTH) 哦!

2.PullToRefreshListView在使用上有一个BUG,在你的xml layout中,不能一开始将它的visiablity设置为GONE,否则,在代码中设置visiablity为VISIABLE也没有作用。





最后放上一张效果图

PullToRefresh使用详解_第1张图片





--------------------------------华丽丽的分割线--------------------------------------


PullToRefresh使用详解(一)--构建下拉刷新的listView

效果图: 

                               正在刷新                                                                       刷新后

PullToRefresh使用详解_第2张图片      PullToRefresh使用详解_第3张图片

一、导入Library

下载源码后(https://github.com/chrisbanes/Android-PullToRefresh),里面有个Library工程,添加工程到Eclipse中;
PullToRefresh使用详解_第4张图片
另外extras文件夹还有两个工程:PullToRefreshListFragment和PullToRefreshViewPager,由于我们的这个用不到他们的库文件,所以不必导入了;

二、实战

1、新建工程,添加Libray库到工程中

新建工程(try_PullToRefresh)后,右键-》Properties-》Android-》Add  选择上面的Library,然后就是这个样子的

PullToRefresh使用详解_第5张图片

2、重写activity_main.xml

XML内容为:

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.       
  7. <!--     The PullToRefreshListView replaces a standard ListView widget. -->  
  8.     <com.handmark.pulltorefresh.library.PullToRefreshListView  
  9.         android:id="@+id/pull_refresh_list"  
  10.         android:layout_width="fill_parent"  
  11.         android:layout_height="fill_parent"  
  12.         android:cacheColorHint="#00000000"  
  13.         android:divider="#19000000"  
  14.         android:dividerHeight="4dp"  
  15.         android:fadingEdge="none"  
  16.         android:fastScrollEnabled="false"  
  17.         android:footerDividersEnabled="false"  
  18.         android:headerDividersEnabled="false"  
  19.         android:smoothScrollbar="true" />  
  20.   
  21. </LinearLayout>  

其中中间那一大段<com.handmark.pull………………/>就是相当于ListView控件,用这段来代替原是ListView控件的代码

3、JAVA代码讲解

全部代码:

[java]  view plain copy
  1. package com.example.try_pulltorefresh;  
  2.   
  3. import java.util.Arrays;  
  4. import java.util.LinkedList;  
  5.   
  6. import com.handmark.pulltorefresh.library.PullToRefreshBase;  
  7. import com.handmark.pulltorefresh.library.PullToRefreshListView;  
  8. import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;  
  9.   
  10. import android.os.AsyncTask;  
  11. import android.os.Bundle;  
  12. import android.app.Activity;  
  13. import android.text.format.DateUtils;  
  14. import android.widget.ArrayAdapter;  
  15. import android.widget.ListView;  
  16.   
  17. public class MainActivity extends Activity {  
  18.     private String[] mStrings = { "Abbaye de Belloc""Abbaye du Mont des Cats""Abertam""Abondance""Ackawi",  
  19.             "Acorn""Adelost""Affidelice au Chablis""Afuega'l Pitu""Airag""Airedale""Aisy Cendre",  
  20.             "Allgauer Emmentaler""Abbaye de Belloc""Abbaye du Mont des Cats""Abertam""Abondance""Ackawi",  
  21.             "Acorn""Adelost""Affidelice au Chablis""Afuega'l Pitu""Airag""Airedale""Aisy Cendre",  
  22.             "Allgauer Emmentaler" };  
  23.     private LinkedList<String> mListItems;  
  24.     private PullToRefreshListView mPullRefreshListView;  
  25.     private ArrayAdapter<String> mAdapter;  
  26.   
  27.     @Override  
  28.     protected void onCreate(Bundle savedInstanceState) {  
  29.         super.onCreate(savedInstanceState);  
  30.         setContentView(R.layout.activity_main);  
  31.           
  32.         mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);  
  33.   
  34.         // Set a listener to be invoked when the list should be refreshed.  
  35.         mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {  
  36.             @Override  
  37.             public void onRefresh(PullToRefreshBase<ListView> refreshView) {  
  38.                 String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),  
  39.                         DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);  
  40.   
  41.                 // Update the LastUpdatedLabel  
  42.                 refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);  
  43.   
  44.                 // Do work to refresh the list here.  
  45.                 new GetDataTask().execute();  
  46.             }  
  47.         });  
  48.   
  49.         mListItems = new LinkedList<String>();  
  50.         mListItems.addAll(Arrays.asList(mStrings));  
  51.   
  52.         mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mListItems);  
  53.   
  54.         //这两个绑定方法用其一  
  55.         // 方法一  
  56. //       mPullRefreshListView.setAdapter(mAdapter);  
  57.         //方法二  
  58.         ListView actualListView = mPullRefreshListView.getRefreshableView();  
  59.         actualListView.setAdapter(mAdapter);  
  60.     }  
  61.   
  62.     private class GetDataTask extends AsyncTask<Void, Void, String> {  
  63.   
  64.         //后台处理部分  
  65.         @Override  
  66.         protected String doInBackground(Void... params) {  
  67.             // Simulates a background job.  
  68.             try {  
  69.                 Thread.sleep(1000);  
  70.             } catch (InterruptedException e) {  
  71.             }  
  72.             String str="Added after refresh...I add";  
  73.             return str;  
  74.         }  
  75.   
  76.         //这里是对刷新的响应,可以利用addFirst()和addLast()函数将新加的内容加到LISTView中  
  77.         //根据AsyncTask的原理,onPostExecute里的result的值就是doInBackground()的返回值  
  78.         @Override  
  79.         protected void onPostExecute(String result) {  
  80.             //在头部增加新添内容  
  81.             mListItems.addFirst(result);  
  82.               
  83.             //通知程序数据集已经改变,如果不做通知,那么将不会刷新mListItems的集合  
  84.             mAdapter.notifyDataSetChanged();  
  85.             // Call onRefreshComplete when the list has been refreshed.  
  86.             mPullRefreshListView.onRefreshComplete();  
  87.   
  88.             super.onPostExecute(result);  
  89.         }  
  90.     }  
  91. }  

代码讲解:
1、变量定义

[java]  view plain copy
  1. private LinkedList<String> mListItems;    //显示的列表对应原字符串  
  2. private PullToRefreshListView mPullRefreshListView;  //PullToRefreshListView实例  
  3. private ArrayAdapter<String> mAdapter;  //ListView的适配器  

2、在OnCreate()中主要分为两步
(1)初始化mPullRefreshListView并设置监听器,以执行当需要刷新时,应该怎么办,至于真正执行刷新的类GetDataTask()我们后面再细讲,对应代码为:

[java]  view plain copy
  1. mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);  
  2.   
  3. // Set a listener to be invoked when the list should be refreshed.  
  4. mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {  
  5.     @Override  
  6.     public void onRefresh(PullToRefreshBase<ListView> refreshView) {  
  7.         String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),  
  8.                 DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);  
  9.   
  10.         // Update the LastUpdatedLabel  
  11.         refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);  
  12.   
  13.         // Do work to refresh the list here.  
  14.         new GetDataTask().execute();  
  15.     }  
  16. });  

(2)设置适配器列表内容,并与ListView绑定以显示出来,对应代码为:

[java]  view plain copy
  1. //设置列表内容  
  2. mListItems = new LinkedList<String>();  
  3. mListItems.addAll(Arrays.asList(mStrings));  
  4. mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mListItems);  
  5.   
  6. //这两个绑定方法用其一  
  7. // 方法一  
  8. //       mPullRefreshListView.setAdapter(mAdapter);  
  9. //方法二  
  10. ListView actualListView = mPullRefreshListView.getRefreshableView();  
  11. actualListView.setAdapter(mAdapter);  

3、执行刷新的类GetDataTask()
先贴出这段代码来:

[java]  view plain copy
  1. private class GetDataTask extends AsyncTask<Void, Void, String> {//定义返回值的类型  
  2.     // 后台处理部分  
  3.     @Override  
  4.     protected String doInBackground(Void... params) {  
  5.         // Simulates a background job.  
  6.         try {  
  7.             Thread.sleep(1000);  
  8.         } catch (InterruptedException e) {  
  9.         }  
  10.         String str="Added after refresh...I add";  
  11.         return str;  
  12.     }  
  13.   
  14.     //这里是对刷新的响应,可以利用addFirst()和addLast()函数将新加的内容加到LISTView中  
  15.     //根据AsyncTask的原理,onPostExecute里的result的值就是doInBackground()的返回值  
  16.     @Override  
  17.     protected void onPostExecute(String result) {  
  18.         //在头部增加新添内容  
  19.         mListItems.addFirst(result);  
  20.           
  21.         //通知程序数据集已经改变,如果不做通知,那么将不会刷新mListItems的集合  
  22.         mAdapter.notifyDataSetChanged();  
  23.         // Call onRefreshComplete when the list has been refreshed.  
  24.         mPullRefreshListView.onRefreshComplete();  
  25.   
  26.         super.onPostExecute(result);//这句是必有的,AsyncTask规定的格式  
  27.     }  
  28. }  
(1)派生自AsyncTask

由于派生自AsyncTask,所以下面的那个函数doInBackground和onPostExecute就不难理解了,这两个函数是AsyncTask必须是重写的两个函数
(2)doInBackground函数

doInBackground执行要于后台执行的语句,返回的值可以是任意类型,但要提前在extends AsyncTask<Void, Void, String> 中定义,这个返回值会做为onPostExecute的参数result传到onPostExecute函数中;如果对于网络访问程序,doInBackground就执行访问网络的代码,然后讲返回值存在result中传给onPostExecute函数,以刷新列表;

 (3)onPostExecute函数

 onPostExecute()是对返回的值进行操作,并添加到ListView的列表中,有两种添加方式添加到头部----mListItems.addFirst(result);和添加在尾部----mListItems.addLast(result);

至于 AsyncTask,下面是几个网页,讲的还可以,大家可以参考下:

 《android AsyncTask 详解》:http://www.eoeandroid.com/thread-168004-1-1.html

 《android AsyncTask 详解》(同名):http://blog.csdn.net/dabizime/article/details/6695705

《android之AsyncTask》:http://blog.csdn.net/singwhatiwanna/article/details/9272195 

《Android源码分析--带你认识不一样的AsyncTask》:http://blog.csdn.net/singwhatiwanna/article/details/17596225 (绝对精品)


 另外:

 1、设置向上拉刷新还是向下拉刷新的代码:

 mPullRefreshListView.setMode(Mode.PULL_FROM_END);//向下拉刷新

 mPullRefreshListView.setMode(Mode.PULL_FROM_START);//向上拉刷新

mPullRefreshListView.setMode(Mode.BOTH);//两端刷新
 

注意:这只是一个精简版,在源码中还有一些可借签的代码,可以在看懂这个以后,可以回过头来再看看源码,我相信肯定会有收获的。

源码来啦:http://download.csdn.net/detail/harvic880925/6788247(不要分,仅供分享)



====================华丽丽的分割线====================



PullToRefresh使用详解(二)---重写BaseAdapter实现复杂XML下拉刷新

效果图:

                                   正在刷新                                                                     刷新后

PullToRefresh使用详解_第6张图片      PullToRefresh使用详解_第7张图片

一、XML代码

1、activity_main.xml

PullToRefresh标准写法,与《PullToRefresh使用详解(一)--构建下拉刷新的ListView》布局一样。

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7. <!--     The PullToRefreshListView replaces a standard ListView widget. -->  
  8.   
  9.     <com.handmark.pulltorefresh.library.PullToRefreshListView  
  10.         android:id="@+id/pull_refresh_list"  
  11.         android:layout_width="fill_parent"  
  12.         android:layout_height="fill_parent"  
  13.         android:cacheColorHint="#00000000"  
  14.         android:divider="#19000000"  
  15.         android:dividerHeight="4dp"  
  16.         android:fadingEdge="none"  
  17.         android:fastScrollEnabled="false"  
  18.         android:footerDividersEnabled="false"  
  19.         android:headerDividersEnabled="false"  
  20.         android:smoothScrollbar="true" />  
  21.   
  22. </LinearLayout>  

2、数据项XML(item.xml)

与《List控件使用--SimpleAdapter使用详解(二)》布局一样,只是将名字改成了item.xml

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="horizontal" android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent">  
  5.   
  6.     <ImageView android:id="@+id/img"   
  7.         android:layout_width="wrap_content"  
  8.         android:layout_height="wrap_content"   
  9.         android:layout_margin="5px"/>  
  10.   
  11.     <LinearLayout android:orientation="vertical"  
  12.         android:layout_width="wrap_content"   
  13.         android:layout_height="wrap_content">  
  14.   
  15.         <TextView android:id="@+id/name"   
  16.             android:layout_width="wrap_content"  
  17.             android:layout_height="wrap_content"   
  18.             android:textColor="#FFFFFF00"  
  19.             android:textSize="22px" />  
  20.         <TextView android:id="@+id/info"   
  21.             android:layout_width="wrap_content"  
  22.             android:layout_height="wrap_content"   
  23.             android:textColor="#FF00FFFF"  
  24.             android:textSize="13px" />  
  25.     </LinearLayout>  
  26.       
  27. </LinearLayout>  

二、JAVA代码

先贴出全部代码,然后再慢慢讲。

完整代码

[java]  view plain copy
  1. package com.example.try_pulltorefresh_map;  
  2. //try_PullToRefresh_map  
  3. /** 
  4.  * 完成了从TXT文本中提取,并向下刷新 
  5.  * blog:http://blog.csdn.net/harvic880925/article/details/17708409 
  6.  * @author harvic 
  7.  * @date  2013-12-31 
  8.  *  
  9.  */  
  10. import java.io.BufferedReader;  
  11. import java.io.IOException;  
  12. import java.io.InputStream;  
  13. import java.io.InputStreamReader;  
  14. import java.io.UnsupportedEncodingException;  
  15. import java.util.ArrayList;  
  16. import java.util.HashMap;  
  17. import org.json.JSONArray;  
  18.   
  19. import com.handmark.pulltorefresh.library.PullToRefreshBase;  
  20. import com.handmark.pulltorefresh.library.PullToRefreshListView;  
  21. import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;  
  22. import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;  
  23.   
  24. import android.os.AsyncTask;  
  25. import android.os.Bundle;  
  26. import android.app.ListActivity;  
  27. import android.content.Context;  
  28. import android.graphics.Bitmap;  
  29. import android.graphics.BitmapFactory;  
  30. import android.text.format.DateUtils;  
  31. import android.view.LayoutInflater;  
  32. import android.view.View;  
  33. import android.view.ViewGroup;  
  34. import android.widget.BaseAdapter;  
  35. import android.widget.ImageView;  
  36. import android.widget.ListView;  
  37. import android.widget.TextView;  
  38.   
  39. public class MainActivity extends ListActivity {  
  40.       
  41.     private ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();  
  42.     private PullToRefreshListView mPullRefreshListView;  
  43.     MyAdapter adapter=null;  
  44.   
  45.     @Override  
  46.     protected void onCreate(Bundle savedInstanceState) {  
  47.         super.onCreate(savedInstanceState);  
  48.         setContentView(R.layout.activity_main);  
  49.           
  50.         mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);  
  51.   
  52.         //设定下拉监听函数  
  53.         mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {  
  54.             @Override  
  55.             public void onRefresh(PullToRefreshBase<ListView> refreshView) {  
  56.                 String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),  
  57.                         DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);  
  58.   
  59.                 // Update the LastUpdatedLabel  
  60.                 refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);  
  61.   
  62.                 // Do work to refresh the list here.  
  63.                 new GetDataTask().execute();  
  64.             }  
  65.         });  
  66.   
  67.         mPullRefreshListView.setMode(Mode.PULL_FROM_END);//设置底部下拉刷新模式  
  68.           
  69.         listItem=getData();//获取LIST数据  
  70.         adapter = new MyAdapter(this);  
  71.   
  72.         //设置适配器  
  73.         ListView actualListView = mPullRefreshListView.getRefreshableView();  
  74.         actualListView.setAdapter(adapter);   
  75.           
  76.     }  
  77.     private class GetDataTask extends AsyncTask<Void, Void, HashMap<String, Object>> {  
  78.   
  79.         //后台处理部分  
  80.         @Override  
  81.         protected HashMap<String, Object> doInBackground(Void... params) {  
  82.             // Simulates a background job.  
  83.             try {  
  84.                 Thread.sleep(1000);  
  85.             } catch (InterruptedException e) {  
  86.             }  
  87.             HashMap<String, Object> map = new HashMap<String, Object>();  
  88.             try {  
  89.                   
  90.                 map = new HashMap<String, Object>();  
  91.                 map.put("name""林珊");  
  92.                 map.put("info""上传了一张新照片油画");  
  93.                 map.put("img","youhua");  
  94.                   
  95.             } catch (Exception e) {  
  96.                 // TODO: handle exception  
  97.                 setTitle("map出错了");  
  98.                 return null;  
  99.             }  
  100.               
  101.             return map;  
  102.         }  
  103.   
  104.         //这里是对刷新的响应,可以利用addFirst()和addLast()函数将新加的内容加到LISTView中  
  105.         //根据AsyncTask的原理,onPostExecute里的result的值就是doInBackground()的返回值  
  106.         @Override  
  107.         protected void onPostExecute(HashMap<String, Object> result) {  
  108.             //在头部增加新添内容  
  109.               
  110.             try {  
  111.                 listItem.add(result);  
  112.                   
  113.                 //通知程序数据集已经改变,如果不做通知,那么将不会刷新mListItems的集合  
  114.                 adapter.notifyDataSetChanged();  
  115.                 // Call onRefreshComplete when the list has been refreshed.  
  116.                 mPullRefreshListView.onRefreshComplete();  
  117.             } catch (Exception e) {  
  118.                 // TODO: handle exception  
  119.                 setTitle(e.getMessage());  
  120.             }  
  121.               
  122.   
  123.             super.onPostExecute(result);  
  124.         }  
  125.     }  
  126.       
  127.     private ArrayList<HashMap<String, Object>> getData() {  
  128.         ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();  
  129.         HashMap<String, Object> map = new HashMap<String, Object>();  
  130.         InputStream inputStream;  
  131.         try {  
  132.             inputStream=this.getAssets().open("my_home_friends.txt");  
  133.             String json=readTextFile(inputStream);  
  134.             JSONArray array = new JSONArray(json);  
  135.             for (int i = 0; i < array.length(); i++) {  
  136.                 map = new HashMap<String, Object>();  
  137.                 map.put("name", array.getJSONObject(i).getString("name"));  
  138.                 map.put("info", array.getJSONObject(i).getString("info"));  
  139.                 map.put("img",array.getJSONObject(i).getString("photo"));  
  140.                 list.add(map);  
  141.             }  
  142.             return list;      
  143.               
  144.         } catch (Exception e) {  
  145.             // TODO: handle exception  
  146.             e.printStackTrace();  
  147.         }  
  148.           
  149.           
  150.         return list;      
  151.     }  
  152.   
  153.       
  154.       
  155.     public final class ViewHolder{  
  156.         public ImageView img;  
  157.         public TextView name;  
  158.         public TextView info;  
  159.     }         
  160.       
  161.     public class MyAdapter extends BaseAdapter{  
  162.   
  163.         private LayoutInflater mInflater;  
  164.           
  165.         public MyAdapter(Context context){  
  166.             this.mInflater = LayoutInflater.from(context);  
  167.         }  
  168.         @Override  
  169.         public int getCount() {  
  170.             // TODO Auto-generated method stub  
  171.             return listItem.size();  
  172.         }  
  173.   
  174.         @Override  
  175.         public Object getItem(int arg0) {  
  176.             // TODO Auto-generated method stub  
  177.             return null;  
  178.         }  
  179.   
  180.         @Override  
  181.         public long getItemId(int arg0) {  
  182.             // TODO Auto-generated method stub  
  183.             return 0;  
  184.         }  
  185.           
  186.         @Override  
  187.         public View getView(int position, View convertView, ViewGroup parent) {  
  188.               
  189.             ViewHolder holder = null;  
  190.             if (convertView == null) {  
  191.                   
  192.                 holder=new ViewHolder();    
  193.                   
  194.                 convertView = mInflater.inflate(R.layout.item, null);  
  195.                 holder.img = (ImageView)convertView.findViewById(R.id.img);  
  196.                 holder.name = (TextView)convertView.findViewById(R.id.name);  
  197.                 holder.info = (TextView)convertView.findViewById(R.id.info);  
  198.                 convertView.setTag(holder);  
  199.                   
  200.             }else {  
  201.                   
  202.                 holder = (ViewHolder)convertView.getTag();  
  203.             }  
  204.               
  205.             holder.img.setImageBitmap(getHome((String)listItem.get(position).get("img")));  
  206.             holder.name.setText((String)listItem.get(position).get("name"));  
  207.             holder.info.setText((String)listItem.get(position).get("info"));  
  208.   
  209.             return convertView;  
  210.         }  
  211.           
  212.     }  
  213.       
  214.       
  215.     /** 
  216.      * 根据图片名称获取主页图片 
  217.      */  
  218.     public Bitmap getHome(String photo){          
  219.         String homeName = photo + ".jpg";  
  220.         InputStream is=null;  
  221.           
  222.         try {  
  223.             is=getAssets().open("home/"+homeName);  
  224.             Bitmap bitmap = BitmapFactory.decodeStream(is);       
  225.             is.close();  
  226.             return bitmap;  
  227.         } catch (Exception e) {  
  228.             e.printStackTrace();  
  229.         }  
  230.          
  231.         return null;  
  232.   
  233.     }  
  234.       
  235.     ////工具类  
  236.     /** 
  237.      *  
  238.      * @param inputStream 
  239.      * @return 
  240.      */  
  241.     public String readTextFile(InputStream inputStream) {  
  242.         String readedStr = "";  
  243.         BufferedReader br;  
  244.         try {  
  245.             br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));  
  246.             String tmp;  
  247.             while ((tmp = br.readLine()) != null) {  
  248.                 readedStr += tmp;  
  249.             }  
  250.             br.close();  
  251.             inputStream.close();  
  252.         } catch (UnsupportedEncodingException e) {  
  253.             e.printStackTrace();  
  254.         } catch (IOException e) {  
  255.             e.printStackTrace();  
  256.         }  
  257.   
  258.         return readedStr;  
  259.     }  
  260.   
  261.   
  262. }  
讲解:

执行流程:
看起来代码挺长,其实只看OnCreate()函数就能知道,只是分成了几大块,先贴出OnCreate()函数

[java]  view plain copy
  1. @Override  
  2. protected void onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     setContentView(R.layout.activity_main);  
  5.       
  6.     mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);  
  7.   
  8.     //设定下拉监听函数  
  9.     mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {  
  10.         @Override  
  11.         public void onRefresh(PullToRefreshBase<ListView> refreshView) {  
  12.             String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),  
  13.                     DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);  
  14.   
  15.             // Update the LastUpdatedLabel  
  16.             refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);  
  17.   
  18.             // Do work to refresh the list here.  
  19.             new GetDataTask().execute();  
  20.         }  
  21.     });  
  22.   
  23.     mPullRefreshListView.setMode(Mode.PULL_FROM_END);//设置底部下拉刷新模式  
  24.       
  25.     listItem=getData();//获取LIST数据  
  26.     adapter = new MyAdapter(this);  
  27.   
  28.     //设置适配器  
  29.     ListView actualListView = mPullRefreshListView.getRefreshableView();  
  30.     actualListView.setAdapter(adapter);   
  31.       
  32. }  

1、首先初始化mPullRefreshListView,然后设定监听函数,监听函数没变,我只是更改了GetDataTask()函数里的部分代码,我相信大家也能看懂,难度不大;

2、设定下拉模式,绑定适配器,对应代码

[java]  view plain copy
  1. mPullRefreshListView.setMode(Mode.PULL_FROM_END);//设置底部下拉刷新模式  
  2.   
  3. listItem=getData();//获取LIST数据  
  4. adapter = new MyAdapter(this);  
  5.   
  6. //设置适配器  
  7. ListView actualListView = mPullRefreshListView.getRefreshableView();  
  8. actualListView.setAdapter(adapter);   



====================华丽丽的分割线====================



PullToRefresh使用详解(三)--实现异步加载的下拉刷新列表

效果图:

   初始化后,正在加载图片            加载出一部分

PullToRefresh使用详解_第8张图片   PullToRefresh使用详解_第9张图片 

          下拉刷新                                      新生成的ITEM                               加载完成新生成ITEM的图片

PullToRefresh使用详解_第10张图片   PullToRefresh使用详解_第11张图片   PullToRefresh使用详解_第12张图片

 一、MainActivity.java

 其它的代码就不讲了,我只说说这个主页面是如何动作的,先看看整体代码。

 

[java]  view plain copy
  1. package com.example.try_simpleadapter_new;  
  2. /** 
  3.  * 完成与服务器通信的下拉刷新 
  4.  * @author harvic 
  5.  */  
  6. import java.io.BufferedReader;  
  7. import java.io.InputStreamReader;  
  8. import java.util.ArrayList;  
  9. import java.util.List;  
  10.   
  11. import org.apache.http.HttpEntity;  
  12. import org.apache.http.HttpResponse;  
  13. import org.apache.http.NameValuePair;  
  14. import org.apache.http.client.entity.UrlEncodedFormEntity;  
  15. import org.apache.http.client.methods.HttpPost;  
  16. import org.apache.http.impl.client.DefaultHttpClient;  
  17. import org.apache.http.message.BasicNameValuePair;  
  18. import org.apache.http.protocol.HTTP;  
  19. import org.json.JSONArray;  
  20.   
  21.   
  22. import com.handmark.pulltorefresh.library.PullToRefreshBase;  
  23. import com.handmark.pulltorefresh.library.PullToRefreshListView;  
  24. import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;  
  25. import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;  
  26.   
  27. import android.os.AsyncTask;  
  28. import android.os.Bundle;  
  29. import android.text.format.DateUtils;  
  30. import android.util.Log;  
  31. import android.widget.ListView;  
  32. import android.app.ListActivity;  
  33.   
  34. public class MainActivity extends ListActivity{  
  35.   
  36.     private String serverIP="http://222.195.151.19";  
  37.     private List<ImageAndText> mData;  
  38.     private PullToRefreshListView mPullRefreshListView;  
  39.     ImageAndTextListAdapter adapter=null;  
  40.     @Override  
  41.     public void onCreate(Bundle savedInstanceState) {  
  42.         super.onCreate(savedInstanceState);  
  43.         setContentView(R.layout.activity_main);   
  44.           
  45.         mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);  
  46.   
  47.         //设定下拉监听函数  
  48.         mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {  
  49.             @Override  
  50.             public void onRefresh(PullToRefreshBase<ListView> refreshView) {  
  51.                 String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),  
  52.                         DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);  
  53.   
  54.                 // Update the LastUpdatedLabel  
  55.                 refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);  
  56.   
  57.                 Log.d("msg","this=="+this);  
  58.                 // Do work to refresh the list here.  
  59.                 new GetDataTask().execute();  
  60.                   
  61.             }  
  62.         });  
  63.   
  64.         mPullRefreshListView.setMode(Mode.PULL_FROM_END);// 设置底部下拉刷新模式  
  65.         //传参生成适配器  
  66.         mData = getData();  
  67.         ListView actualListView = mPullRefreshListView.getRefreshableView();  
  68.         adapter = new ImageAndTextListAdapter(this,mData,actualListView);  
  69.           
  70.         // 设置适配器  
  71.         actualListView.setAdapter(adapter);       
  72.     }  
  73.       
  74.     private List<ImageAndText> getData() {  
  75.         //创建默认的httpClient实例.    
  76.                 DefaultHttpClient httpclient = new DefaultHttpClient();   
  77.                 HttpResponse response = null;  
  78.                 HttpEntity entity = null;  
  79.                   
  80.                 StringBuilder builder = new StringBuilder();    
  81.                 JSONArray jsonArray = null;    
  82.                   
  83.                 List<ImageAndText> list = new ArrayList<ImageAndText>();                  
  84.                                                                        
  85.                 try{  
  86.                      // 创建httpost.访问本地服务器网址    
  87.                     HttpPost httpost = new HttpPost(serverIP+"/try_an_server/index.php");     
  88.                       
  89.                      //构造POST方法的{name:value} 参数对  
  90.                      List <NameValuePair>  vps = new ArrayList <NameValuePair>();     
  91.                      //将参数传入post方法中  
  92.                      vps.add(new BasicNameValuePair("action""insert"));    
  93.                      vps.add(new BasicNameValuePair("name""进去了"));  
  94.                                    
  95.                     httpost.setEntity(new UrlEncodedFormEntity(vps, HTTP.UTF_8));  
  96.                     response = httpclient.execute(httpost);  //执行  
  97.                       
  98.                     if (response.getEntity() != null) {               
  99.                         //如果服务器端JSON没写对,这句是会出异常,是执行不过去的  
  100.                      BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));    
  101.                      String s = reader.readLine();  
  102.                      for (; s != null; s = reader.readLine()) {   
  103.                          builder.append(s);    
  104.                      }    
  105.                      Log.i("msg","builder.toString = "+ builder.toString());   
  106.                        
  107.                      jsonArray = new JSONArray(builder.toString());    
  108.                      for (int i = 0; i < jsonArray.length(); i++) {  
  109.                          if(jsonArray.getJSONObject(i).getInt("id")==1){  
  110.                              String name=jsonArray.getJSONObject(i).getString("name");  
  111.                              String info=jsonArray.getJSONObject(i).getString("info");  
  112.                              String PicName=jsonArray.getJSONObject(i).getString("photo");  
  113.                              String picURL=serverIP+"/try_an_server/"+PicName+".jpg";  
  114.                                
  115.                             ImageAndText item=new ImageAndText(picURL,name,info);  
  116.                             list.add(item);  
  117.                          }  
  118.                      }  
  119.                     }  
  120.                 } catch (Exception e) {  
  121.                     e.printStackTrace();  
  122.                 } finally {  
  123.                     try {  
  124.                          if (entity != null)  
  125.                          {  
  126.                             httpclient.getConnectionManager().shutdown();//关闭连接  
  127.                             //这两种释放连接的方法都可以  
  128.                          }  
  129.                     } catch (Exception e) {  
  130.                         // TODO Auto-generated catch block  
  131.                         e.printStackTrace();  
  132.                     }    
  133.                 }  
  134.   
  135.             return list;      
  136.       
  137.     }  
  138.       
  139.       
  140.       
  141.     private class GetDataTask extends AsyncTask<Void, Void, ImageAndText> {  
  142.   
  143.         //后台处理部分  
  144.         @Override  
  145.         protected ImageAndText doInBackground(Void... params) {  
  146.             // Simulates a background job.  
  147.             ImageAndText item = null;  
  148.             try {  
  149.                 item = new ImageAndText(serverIP+"/try_an_server/xizang.jpg""sss""ssss");                 
  150.             } catch (Exception e) {  
  151.                 // TODO: handle exception  
  152.                 setTitle("map出错了");  
  153.             }  
  154.               
  155.             return item;  
  156.         }  
  157.   
  158.         //这里是对刷新的响应,可以利用addFirst()和addLast()函数将新加的内容加到LISTView中  
  159.         //根据AsyncTask的原理,onPostExecute里的result的值就是doInBackground()的返回值  
  160.         @Override  
  161.         protected void onPostExecute(ImageAndText result) {  
  162.             //在头部增加新添内容  
  163.               
  164.             try {  
  165.                 mData.add(result);  
  166.                   
  167.                 //通知程序数据集已经改变,如果不做通知,那么将不会刷新mListItems的集合  
  168.                 adapter.notifyDataSetChanged();  
  169.                 adapter.loadImage();  
  170.                 // Call onRefreshComplete when the list has been refreshed.  
  171.                 mPullRefreshListView.onRefreshComplete();  
  172.             } catch (Exception e) {  
  173.                 // TODO: handle exception  
  174.                 setTitle(e.getMessage());  
  175.             }  
  176.   
  177.             super.onPostExecute(result);  
  178.         }  
  179.     }  
  180.       
  181.   
  182. }  

分开讲解:
1、先看OnCreate()函数

[java]  view plain copy
  1. mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);  
  2.   
  3. //设定下拉监听函数  
  4. mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {  
  5.     @Override  
  6.     public void onRefresh(PullToRefreshBase<ListView> refreshView) {  
  7.         String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),  
  8.                 DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);  
  9.   
  10.         // Update the LastUpdatedLabel  
  11.         refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);  
  12.   
  13.         Log.d("msg","this=="+this);  
  14.         // Do work to refresh the list here.  
  15.         new GetDataTask().execute();  
  16.           
  17.     }  
  18. });  

这段代码先初始化了mPullRefreshListView,然后设置了下拉监听的函数,在下拉时执行GetDataTask()函数;
2、看看GetDataTask()函数做了那些改动

[java]  view plain copy
  1. private class GetDataTask extends AsyncTask<Void, Void, ImageAndText> {  
  2.     //后台处理部分  
  3.     @Override  
  4.     protected ImageAndText doInBackground(Void... params) {  
  5.         // Simulates a background job.  
  6.         ImageAndText item = null;  
  7.         try {  
  8.             item = new ImageAndText(serverIP+"/try_an_server/xizang.jpg""sss""ssss");                 
  9.         } catch (Exception e) {  
  10.             // TODO: handle exception  
  11.             setTitle("map出错了");  
  12.         }  
  13.           
  14.         return item;  
  15.     }  
  16.   
  17.     //这里是对刷新的响应,可以利用addFirst()和addLast()函数将新加的内容加到LISTView中  
  18.     //根据AsyncTask的原理,onPostExecute里的result的值就是doInBackground()的返回值  
  19.     @Override  
  20.     protected void onPostExecute(ImageAndText result) {  
  21.         //在头部增加新添内容  
  22.           
  23.         try {  
  24.             mData.add(result);  
  25.               
  26.             //通知程序数据集已经改变,如果不做通知,那么将不会刷新mListItems的集合  
  27.             adapter.notifyDataSetChanged();  
  28.             adapter.loadImage();  
  29.             // Call onRefreshComplete when the list has been refreshed.  
  30.             mPullRefreshListView.onRefreshComplete();  
  31.         } catch (Exception e) {  
  32.             // TODO: handle exception  
  33.             setTitle(e.getMessage());  
  34.         }  
  35.   
  36.         super.onPostExecute(result);  
  37.     }  
  38. }  

在doInBackground()中新增了一个ITEM项,然后在onPostExecute()中将这个项加入到mData数据列表中,然后利用adapter.notifyDataSetChanged();通知数据集已经改变;
3、继续OnCreate()函数的剩余部分

[java]  view plain copy
  1. mPullRefreshListView.setMode(Mode.PULL_FROM_END);// 设置底部下拉刷新模式  
  2. //传参生成适配器  
  3. mData = getData();  
  4. ListView actualListView = mPullRefreshListView.getRefreshableView();  
  5. adapter = new ImageAndTextListAdapter(this,mData,actualListView);  
  6.   
  7. // 设置适配器  
  8. actualListView.setAdapter(adapter);       

首先是设计下拉刷新模式,然后利用GetData()函数返回参数列表,再利用ImageAndTextListAdapter()类生成adapter,最后利用setAdapter()来加载适配器;
 最后就只一个getData()函数没讲了,其实就是向服务器请求JSON数据,然后生成List变量,并返回;代码比较简单,不说了;

 存在问题:最需要注意的是这个东东我在手机上测试是存在问题的,当缓慢滑到顶端或底端时,在onScrollStateChanged()监听函数中并不会激发AbsListView.OnScrollListener.SCROLL_STATE_IDLE:这一项,所以会出现不加载图片的情况,一直显示空白图,我上网搜了下,是手机的问题,不是代码的毛病,但这是很有问题的,最后,我看了其它的应用程序,我还是把上下划动是停止加载的这段代码去掉了,让他一上来就加载,无论用户是否在滑动。至于后面会不会遇到什么问题就后面再说吧,如果哪位大神有好的解决办法,欢迎拍砖!




====================华丽丽的分割线====================



PullToRefresh使用详解(四)--利用回调函数实现到底加载

效果:

   当快到底的时候,程序会自动加载后面的列表

PullToRefresh使用详解_第13张图片

这篇较上篇的改动:

1、去掉了线程互斥加载,直接开线程加载当前IMG,即不判断当前用户是不是在划屏了啥啥的,只要调用到getView()一概加载;

2、重写了ImageAndTextListAdapter类;

一、先看ImageAndTextListAdapter类

全部代码:

[java]  view plain copy
  1. package com.example.try_simpleadapter_new;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import com.example.try_simpleadapter_new.AsyncImageLoader.ImageCallback;  
  7. import com.handmark.pulltorefresh.library.PullToRefreshListView;  
  8.   
  9. import android.R.bool;  
  10. import android.app.Activity;  
  11. import android.graphics.drawable.Drawable;  
  12. import android.graphics.drawable.Drawable.Callback;  
  13. import android.util.Log;  
  14. import android.view.LayoutInflater;  
  15. import android.view.View;  
  16. import android.view.ViewGroup;  
  17. import android.view.ScaleGestureDetector.OnScaleGestureListener;  
  18. import android.widget.AbsListView;  
  19. import android.widget.BaseAdapter;  
  20. import android.widget.ImageView;  
  21. import android.widget.ListView;  
  22. import android.widget.TextView;  
  23.   
  24. public class ImageAndTextListAdapter extends BaseAdapter{  
  25.   
  26.         private LayoutInflater inflater;  
  27.         private ListView listView;  
  28.         private AsyncImageLoader asyncImageLoader;  
  29.         private List<ImageAndText> dataArray=new ArrayList<ImageAndText>();  
  30.           
  31.         private ScrollToLastCallBack mScrollToLastCallBack=null;  
  32.   
  33.         public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts,   
  34.                 ListView listView,final ScrollToLastCallBack scrollToLastCallBack) {  
  35.   
  36.             this.listView = listView;  
  37.             asyncImageLoader = new AsyncImageLoader();  
  38.             inflater = activity.getLayoutInflater();  
  39.             dataArray=imageAndTexts;  
  40.               
  41.             mScrollToLastCallBack=scrollToLastCallBack;  
  42.         }  
  43.           
  44.         public interface ScrollToLastCallBack  
  45.         {  
  46.             public void onScrollToLast(Integer pos);  
  47.         }  
  48.           
  49.         @Override  
  50.         public int getCount() {  
  51.             // TODO Auto-generated method stub  
  52.             return dataArray.size();  
  53.         }  
  54.         @Override  
  55.         public Object getItem(int position) {  
  56.             // TODO Auto-generated method stub  
  57.             if(position >= getCount()){  
  58.                 return null;  
  59.             }  
  60.             return dataArray.get(position);  
  61.         }  
  62.         @Override  
  63.         public long getItemId(int position) {  
  64.             // TODO Auto-generated method stub  
  65.             return position;  
  66.         }  
  67.         @Override  
  68.         public View getView(int position, View convertView, ViewGroup parent) {  
  69.             if (convertView == null) {  
  70.                  convertView = inflater.inflate(R.layout.item, null);  
  71.             }  
  72.             convertView.setTag(position);  
  73.               
  74.             ImageAndText imageAndText = (ImageAndText) getItem(position);  
  75.             String imageUrl = imageAndText.getImageUrl();  
  76.               
  77.             TextView nameView =  (TextView) convertView.findViewById(R.id.name);   
  78.             nameView.setText(imageAndText.getName());  
  79.             TextView infoView =  (TextView) convertView.findViewById(R.id.info);   
  80.             infoView.setText(imageAndText.getInfo());  
  81.               
  82.             ImageView iv = (ImageView) convertView.findViewById(R.id.img);  
  83.             iv.setBackgroundResource(R.drawable.rc_item_bg);  
  84.               
  85.             // 加载IMG,并设定到ImageView中  
  86.             asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() {  
  87.                 @Override  
  88.                 public void onImageLoad(Integer pos, Drawable drawable) {  
  89.                     Log.d("msg",pos+ "正在贴");  
  90.                     View view = listView.findViewWithTag(pos);  
  91.                     if(view != null){  
  92.                         ImageView iv = (ImageView) view.findViewById(R.id.img);  
  93.                         iv.setBackgroundDrawable(drawable);  
  94.                         Log.d("msg","贴成功了");  
  95.                     }  
  96.                 }  
  97.                 //加载不成功的图片处理      
  98.                 @Override  
  99.                 public void onError(Integer pos) {  
  100.                     View view = listView.findViewWithTag(pos);  
  101.                     if(view != null){  
  102.                         ImageView iv = (ImageView) view.findViewById(R.id.img);  
  103.                         iv.setBackgroundResource(R.drawable.rc_item_bg);  
  104.                     }  
  105.                     Log.d("msg","没贴成功");  
  106.                 }  
  107.                   
  108.             });  
  109.             
  110.           //判断当前列表所在位置,当到最后两项时就加载  
  111.             int end=listView.getLastVisiblePosition();  
  112.             if(end>getCount()-3&&end<getCount()-1&&end<=getCount())  
  113.             {  
  114.                 mScrollToLastCallBack.onScrollToLast(position);  
  115.             }  
  116.             return convertView;  
  117.         }  
  118. }  
1、第一个改动,增加了接口

[java]  view plain copy
  1. public interface ScrollToLastCallBack  
  2. {  
  3.     public void onScrollToLast(Integer pos);  
  4. }  
2、ImageAndTextListAdapter构造函数

[java]  view plain copy
  1. public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts,   
  2.         ListView listView,final ScrollToLastCallBack scrollToLastCallBack) {  
  3.   
  4.     this.listView = listView;  
  5.     asyncImageLoader = new AsyncImageLoader();  
  6.     inflater = activity.getLayoutInflater();  
  7.     dataArray=imageAndTexts;  
  8.       
  9.     mScrollToLastCallBack=scrollToLastCallBack;  
  10. }  
增加了ScrollToLastCallBack的传递,说明在构造ImageAndTextListAdapter变量时,要传进来ScrollToLastCallBack回调函数的实例,咱们看看这个函数在哪里调用
3、调用位置public View getView(……) 

[java]  view plain copy
  1.   //判断当前列表所在位置,当到最后两项时就加载  
  2. int end=listView.getLastVisiblePosition();  
  3. if(getCount()-2<=end&&end<=getCount())  
  4. {  
  5.     mScrollToLastCallBack.onScrollToLast(position);  
  6. }  
在getView(……)函数中,首先获得当前的显示位置,如果当前的显示位置在最后两个ITEM里了,这里就调用mScrollToLastCallBack.onScrollToLast(position)回调函数,下面我们再看看这个回调函数传进去的时候是怎么写的。

二、MainActivity.java

这里我们只看OnCreate()函数,其它地方都没变

[java]  view plain copy
  1.     public void onCreate(Bundle savedInstanceState) {  
  2.         super.onCreate(savedInstanceState);  
  3.         setContentView(R.layout.activity_main);   
  4.           
  5.         mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);  
  6.   
  7.         //设定下拉监听函数  
  8.         mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {  
  9.             @Override  
  10.             public void onRefresh(PullToRefreshBase<ListView> refreshView) {  
  11.                 String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),  
  12.                         DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);  
  13.   
  14.                 // Update the LastUpdatedLabel  
  15.                 refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);  
  16.   
  17.                 // Do work to refresh the list here.  
  18.                 new GetDataTask().execute();  
  19.                   
  20.             }  
  21.         });  
  22.           
  23. //       当用户拉到底时调用  
  24.         mPullRefreshListView.setOnLastItemVisibleListener(new OnLastItemVisibleListener() {  
  25.             @Override  
  26.             public void onLastItemVisible() {  
  27.                 Toast.makeText(MainActivity.this"End of List!", Toast.LENGTH_SHORT).show();  
  28. //              // 到底时加载任务  
  29. //              new GetDataTask().execute();  
  30.             }  
  31.         });     //PullToRefreshBase  
  32.           
  33.         mPullRefreshListView.setMode(Mode.PULL_FROM_START);// 设置底部下拉刷新模式  
  34.         //传参生成适配器  
  35.         mData = getData();  
  36.         ListView actualListView = mPullRefreshListView.getRefreshableView();  
  37.           
  38.         //自己写的回调函数,监听当前列表是否到了倒数第二个列表项  
  39.         ScrollToLastCallBack scrollToLastCallBack=new ScrollToLastCallBack(){  
  40.   
  41.             @Override  
  42.             public void onScrollToLast(Integer pos) {  
  43.                 // TODO Auto-generated method stub  
  44.                 Toast.makeText(MainActivity.this"到倒数第二个了,加载哈", Toast.LENGTH_SHORT).show();  
  45.                 // 到底时加载任务  
  46.                 new GetDataTask().execute();  
  47.             }  
  48.               
  49.         };  
  50.         adapter = new ImageAndTextListAdapter(this,mData,actualListView,scrollToLastCallBack);  
  51.   
  52.         // 设置适配器  
  53.         actualListView.setAdapter(adapter);       
  54.     }  
这里的变动在最下面,看这段代码:
[java]  view plain copy
  1. //自己写的回调函数,监听当前列表是否到了倒数第二个列表项  
  2. ScrollToLastCallBack scrollToLastCallBack=new ScrollToLastCallBack(){  
  3.   
  4.     @Override  
  5.     public void onScrollToLast(Integer pos) {  
  6.         // TODO Auto-generated method stub  
  7.         Toast.makeText(MainActivity.this"到倒数第二个了,加载哈", Toast.LENGTH_SHORT).show();  
  8.         // 到底时加载任务  
  9.         new GetDataTask().execute();  
  10.     }  
  11.       
  12. };  
  13. adapter = new ImageAndTextListAdapter(this,mData,actualListView,scrollToLastCallBack);  
先构造一个scrollToLastCallBack回调函数,函数内容就是当到倒数第二个ITEM时提示,然后执行加载任务(GetDataTask()),最后将其传到ImageAndTextListAdapter构造函数中。

OK,到这就结束了,其实就是一个回调函数的书写,难度不大,只是在涉及代码量大了的话就相对来讲有点小难度了。

 

更正声明:

原来这段代码:

[java]  view plain copy
  1. int end=listView.getLastVisiblePosition();  
  2. if(getCount()-2<=end&&end<=getCount())  
  3. {  
  4.     mScrollToLastCallBack.onScrollToLast(position);  
  5. }  

所存在的问题:我原本打算到倒数第二个ITEM出现时自动加载列表,但这里没能准确定位到倒数第二个ITEM,当倒数第一个ITEM出现时仍然符合条件,致使加载两次,有时出现列表重复的情况;下面更改

[java]  view plain copy
  1. int end=listView.getLastVisiblePosition();  
  2. if(end>getCount()-3&&getCount()-1<end&&end<=getCount())  
  3. {  
  4.     mScrollToLastCallBack.onScrollToLast(position);  
  5. }  




====================华丽丽的分割线====================



PullToRefresh使用详解(五)--下拉刷新的ScrollView

本篇效果图:

             下拉前                                               下拉中                                       下拉后

 PullToRefresh使用详解_第14张图片    PullToRefresh使用详解_第15张图片 PullToRefresh使用详解_第16张图片

 效果讲解:

1、本例仅讲解上拉加载,对于其它加载内容,参考pullToRefresh源码,在PullToRefreshListActivity.java中写的很详细;

2、上拉加载前,有一个XML布局,下拉刷新后,添加一个与原有布局完全相同的动态布局,只是TextView的内容不一样了而已。

 一、下拉前

 1、导入Library库,至于导入Library库的过程,参考PullToRefresh使用详解(一)--构建下拉刷新的listView》。

 2、XML构建:

[html]  view plain copy
  1. <LinearLayout 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.     android:orientation="vertical"  
  6.     tools:context=".MainActivity" >  
  7.   
  8.     <!-- The PullToRefreshScrollView replaces a standard PullToRefreshScrollView widget. -->  
  9.   
  10.     <com.handmark.pulltorefresh.library.PullToRefreshScrollView  
  11.         xmlns:ptr="http://schemas.android.com/apk/res-auto"  
  12.         android:id="@+id/pull_refresh_scrollview"  
  13.         android:layout_width="fill_parent"  
  14.         android:layout_height="fill_parent"  
  15.         ptr:ptrAnimationStyle="flip"  
  16.         ptr:ptrMode="both" >  
  17.   
  18.         <LinearLayout  
  19.             android:id="@+id/sub_root_lin"  
  20.             android:layout_width="fill_parent"  
  21.             android:layout_height="wrap_content"  
  22.             android:orientation="vertical" >  
  23.   
  24.             <!-- 动态创建布局开始 -->  
  25.             <LinearLayout  
  26.                 android:layout_width="fill_parent"  
  27.                 android:layout_height="wrap_content"  
  28.                 android:orientation="vertical" >  
  29.   
  30.                 <RelativeLayout  
  31.                     android:layout_width="fill_parent"  
  32.                     android:layout_height="wrap_content" >  
  33.   
  34.                     <ImageView  
  35.                         android:layout_width="50dip"  
  36.                         android:layout_height="50dip"  
  37.                         android:layout_alignParentRight="true"  
  38.                         android:clickable="true"  
  39.                         android:padding="5dip"  
  40.                         android:src="@drawable/list_item_detail_part_navi_edit" />  
  41.   
  42.                     <TextView  
  43.                         android:layout_width="fill_parent"  
  44.                         android:layout_height="50dip"  
  45.                         android:gravity="center_horizontal|center_vertical"  
  46.                         android:text="(二)"  
  47.                         android:textSize="20sp"  
  48.                         android:textStyle="bold" />  
  49.                 </RelativeLayout>  
  50.   
  51.                 <TextView  
  52.                     android:layout_width="fill_parent"  
  53.                     android:layout_height="match_parent"  
  54.                     android:text="@string/changHenGe"  
  55.                     android:textSize="20sp" />  
  56.             </LinearLayout>  
  57.             <!-- 动态创建布局结束 -->  
  58.               
  59.         </LinearLayout>  
  60.           
  61.     </com.handmark.pulltorefresh.library.PullToRefreshScrollView>  
  62.   
  63. </LinearLayout>  

这段代码实现的效果就如“下拉前”这张图片显示的一样。

注意两点:

1、利用<com.handmark.pulltorefresh.library.PullToRefreshScrollView取代原有的ScrollView应在的位置即可,其它想怎么布局怎么布局。
2、在<!--动态创建布局-->标注起来的部分,这段代码要格外注意,因为我们在代码中,会创建一个完全相同的动态布局,插入到它上面。

2、JAVA代码 

 完整代码如下:

[java]  view plain copy
  1. package com.example.try_pulltorefresh_listview;  
  2. /** 
  3.  * @author harvic 
  4.  * @date 2014-4-29 
  5.  * @address http://blog.csdn.net/harvic880925 
  6.  */  
  7. import com.handmark.pulltorefresh.library.PullToRefreshBase;  
  8. import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;  
  9. import com.handmark.pulltorefresh.library.PullToRefreshScrollView;  
  10. import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;  
  11.   
  12. import android.os.AsyncTask;  
  13. import android.os.Bundle;  
  14. import android.app.Activity;  
  15. import android.graphics.Typeface;  
  16. import android.util.Log;  
  17. import android.view.Gravity;  
  18. import android.widget.ImageView;  
  19. import android.widget.LinearLayout;  
  20. import android.widget.RelativeLayout;  
  21. import android.widget.ScrollView;  
  22. import android.widget.TextView;  
  23.   
  24. public class MainActivity extends Activity {  
  25.     PullToRefreshScrollView mPullRefreshScrollView;  
  26.     ScrollView mScrollView;  
  27.   
  28.     @Override  
  29.     protected void onCreate(Bundle savedInstanceState) {  
  30.         super.onCreate(savedInstanceState);  
  31.         setContentView(R.layout.activity_main);  
  32.           
  33.         //这几个刷新Label的设置  
  34.         mPullRefreshScrollView = (PullToRefreshScrollView) findViewById(R.id.pull_refresh_scrollview);  
  35.         mPullRefreshScrollView.getLoadingLayoutProxy().setLastUpdatedLabel("lastUpdateLabel");   
  36.         mPullRefreshScrollView.getLoadingLayoutProxy().setPullLabel("PULLLABLE");  
  37.         mPullRefreshScrollView.getLoadingLayoutProxy().setRefreshingLabel("refreshingLabel");  
  38.         mPullRefreshScrollView.getLoadingLayoutProxy().setReleaseLabel("releaseLabel");  
  39.           
  40.         //上拉、下拉设定  
  41.         mPullRefreshScrollView.setMode(Mode.PULL_FROM_START);  
  42.           
  43.         //上拉监听函数  
  44.         mPullRefreshScrollView.setOnRefreshListener(new OnRefreshListener<ScrollView>() {  
  45.               
  46.             @Override  
  47.             public void onRefresh(PullToRefreshBase<ScrollView> refreshView) {  
  48.                 //执行刷新函数  
  49.                 new GetDataTask().execute();  
  50.             }  
  51.         });  
  52.   
  53.         //获取ScrollView布局,此文中用不到  
  54.         mScrollView = mPullRefreshScrollView.getRefreshableView();  
  55.     }  
  56.   
  57.     private class GetDataTask extends AsyncTask<Void, Void, LinearLayout> {  
  58.   
  59.         @Override  
  60.         protected LinearLayout doInBackground(Void... params) {  
  61.             // Simulates a background job.  
  62.             try {  
  63.                 Thread.sleep(4000);  
  64.                 LinearLayout lin=viewSingleItem();  
  65.                 return lin;  
  66.             } catch (InterruptedException e) {  
  67.                 Log.e("msg","GetDataTask:" + e.getMessage());  
  68.             }  
  69.             return null;  
  70.         }  
  71.   
  72.         @Override  
  73.         protected void onPostExecute(LinearLayout result) {  
  74.             // Do some stuff here  
  75.   
  76.             LinearLayout sub_root_lin=(LinearLayout) findViewById(R.id.sub_root_lin);  
  77.               
  78.             LinearLayout.LayoutParams LP_FW = new LinearLayout.LayoutParams(  
  79.                     LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);  
  80.             sub_root_lin.addView(result, 0, LP_FW);  
  81.               
  82.             mPullRefreshScrollView.setMode(Mode.DISABLED);  
  83.               
  84.             // Call onRefreshComplete when the list has been refreshed.  
  85.             //在更新UI后,无需其它Refresh操作,系统会自己加载新的listView  
  86.             mPullRefreshScrollView.onRefreshComplete();  
  87.               
  88.               
  89.             super.onPostExecute(result);  
  90.         }  
  91.     }  
  92.       
  93.     /** 
  94.      * 下拉刷新后,动态产生的一条布局 
  95.      * @return 
  96.      */  
  97.     private LinearLayout viewSingleItem()  
  98.     {  
  99.         LinearLayout layout_root_lin=new LinearLayout(this);  
  100.         layout_root_lin.setOrientation(LinearLayout.VERTICAL);  
  101.           
  102.         //添加第一个子布局集  
  103.         RelativeLayout layout_sub_relative=new RelativeLayout(this);  
  104.           
  105.         ImageView relative_sub_IV=new ImageView(this);  
  106.         relative_sub_IV.setPadding(5555);  
  107.         relative_sub_IV.setClickable(true);  
  108.         relative_sub_IV.setImageResource(R.drawable.list_item_detail_part_navi_edit);  
  109.         RelativeLayout.LayoutParams RL_IM = new RelativeLayout.LayoutParams(50,50);//尤其注意这个位置,用的是父容器的布局参数  
  110.         RL_IM.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);//这里要注意设置方法!!!---靠父容器右侧对齐  
  111.         layout_sub_relative.addView(relative_sub_IV, RL_IM);  
  112.           
  113.         TextView relative_sub_TV=new TextView(this);  
  114.         relative_sub_TV.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.CENTER_VERTICAL);  
  115.         relative_sub_TV.setText("(一)");  
  116.         relative_sub_TV.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));  
  117.         relative_sub_TV.setTextSize(20);  
  118.         RelativeLayout.LayoutParams RL_TV = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,50);  
  119.         layout_sub_relative.addView(relative_sub_TV, RL_TV);  
  120.           
  121.         LinearLayout.LayoutParams LP_FW = new LinearLayout.LayoutParams(  
  122.                 LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);  
  123.         layout_root_lin.addView(layout_sub_relative, LP_FW);  
  124.           
  125.         //添加第二个子布局  
  126.         TextView lin_sub_TV=new TextView(this);  
  127.         lin_sub_TV.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.CENTER_VERTICAL);  
  128.         lin_sub_TV.setText("四月十七,正是去年今日,别君时。忍泪佯低面,含羞半敛眉。" +  
  129.                            "不知魂已断,空有梦相随。除却天边月,没人知。");  
  130.         lin_sub_TV.setTextSize(20);  
  131.         layout_root_lin.addView(lin_sub_TV, LP_FW);  
  132.           
  133.         return layout_root_lin;  
  134.           
  135.           
  136.     }  
  137. }  

讲解:
 1、最长的一个函数:viewSingleItem()

这个函数的功能,就是动态创建一个上面我们所讲的<!-- 动态创建布局 -->之间的布局,并返回根结点,对于动态布局的创建参考《动态添加综合布局---动态添加控件及将某XML动态加入到Activity显示(续)》和《动态添加控件及将某XML动态加入到Activity显示》。

2、然后从上往下看一:刷新标签设定

[java]  view plain copy
  1. mPullRefreshScrollView = (PullToRefreshScrollView) findViewById(R.id.pull_refresh_scrollview);  
  2. mPullRefreshScrollView.getLoadingLayoutProxy().setLastUpdatedLabel("lastUpdateLabel");   
  3. mPullRefreshScrollView.getLoadingLayoutProxy().setPullLabel("PULLLABLE");  
  4. mPullRefreshScrollView.getLoadingLayoutProxy().setRefreshingLabel("refreshingLabel");  
  5. mPullRefreshScrollView.getLoadingLayoutProxy().setReleaseLabel("releaseLabel");  
这几行代码就是设置下拉刷新时那些标签所显示的内容,自定义标签内容的方法,自己试试改几个,看看效果就知道哪个函数对应哪个标签了。我这里列出了所有的标签,供大家理解清楚各自功能。

 3、设置下拉、上拉、上下拉刷新模式

这里是上拉刷新

[java]  view plain copy
  1. mPullRefreshScrollView.setMode(Mode.PULL_FROM_START);  
4、设置上拉刷新监听函数

[java]  view plain copy
  1. mPullRefreshScrollView.setOnRefreshListener(new OnRefreshListener<ScrollView>() {  
  2.       
  3.     @Override  
  4.     public void onRefresh(PullToRefreshBase<ScrollView> refreshView) {  
  5.         //执行刷新函数  
  6.         new GetDataTask().execute();  
  7.     }  
  8. });  
对于真正执行的部分在GetDataTask()函数,下面是它的实现源码:

[java]  view plain copy
  1. private class GetDataTask extends AsyncTask<Void, Void, LinearLayout> {  
  2.     @Override  
  3.     protected LinearLayout doInBackground(Void... params) {  
  4.         // Simulates a background job.  
  5.         try {  
  6.             Thread.sleep(4000);  
  7.             LinearLayout lin=viewSingleItem();  
  8.             return lin;  
  9.         } catch (InterruptedException e) {  
  10.             Log.e("msg","GetDataTask:" + e.getMessage());  
  11.         }  
  12.         return null;  
  13.     }  
  14.   
  15.     @Override  
  16.     protected void onPostExecute(LinearLayout result) {  
  17.         // Do some stuff here  
  18.   
  19.         LinearLayout sub_root_lin=(LinearLayout) findViewById(R.id.sub_root_lin);  
  20.         LinearLayout.LayoutParams LP_FW = new LinearLayout.LayoutParams(  
  21.                 LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);  
  22.         sub_root_lin.addView(result, 0, LP_FW);  
  23.           
  24.         mPullRefreshScrollView.setMode(Mode.DISABLED);  
  25.           
  26.         // Call onRefreshComplete when the list has been refreshed.  
  27.         //在更新UI后,无需其它Refresh操作,系统会自己加载新的listView  
  28.         mPullRefreshScrollView.onRefreshComplete();  
  29.         super.onPostExecute(result);  
  30.     }  
  31. }  
首先为了实现异步加载,派生自AsyncTask,对于AsyncTask的具体解释,后面应该会再开篇具体讲述,这里先粗略的说下:

 1、doInBackground()中产生一条动态布局,并作为最终结果返回;

 2、onPostExecute()接收到这条动态布局结果,添加到XML中并显示,注意这里并没有更新XML view所使用的setContentView(),而是程序自动给加载了。最后利用SetMode取消下拉刷新。



使用PullToRefresh实现下拉刷新和上拉加载

PullToRefresh是一套实现非常好的下拉刷新库,它支持:

1.ListView

2.ExpandableListView

3.GridView

4.WebView

等多种常用的需要刷新的View类型,而且使用起来也十分方便。

(下载地址:https://github.com/chrisbanes/Android-PullToRefresh)


下载完成,将它导入到eclipse中,作为一个library导入到你的工程中就好了。


一、废话少说,下拉刷新go。

 1.在你的布局文件中加上你想用的View就好了,比如这儿我想用一个支持下拉 刷新的ExpandableListView

[html]  view plain copy
  1. <com.handmark.pulltorefresh.library.PullToRefreshExpandableListView  
  2.     android:id="@+id/expand_list"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" />  

2. 在你的Activity代码中进行简单的设置:

[java]  view plain copy
  1. mExpandList = (PullToRefreshExpandableListView) rootView.findViewById(R.id.expand_list);  
  2. mExpandList.getRefreshableView().setGroupIndicator(null);  
  3. mExpandList.getRefreshableView().setDivider(null);  
  4. mExpandList.getRefreshableView().setSelector(android.R.color.transparent);  
  5. mExpandList.getRefreshableView().setOnGroupClickListener(this);  
  6. mExpandList.setOnRefreshListener(this);  

第一行是找到这个View,最后一行是为它加上刷新的监听器,中间的几行是我对ExpandableListView进行一些设置。

这样其实就已经可以下拉刷新了,但刷新时需要运行的代码写在哪呢,还有为什么下拉不会收起来呢,且往下看。


3.下拉刷新时执行的方法onRefresh()

[java]  view plain copy
  1. @Override  
  2. public void onRefresh(PullToRefreshBase<ExpandableListView> refreshView) {  
  3.     if (!isRefreshing) {  
  4.         isRefreshing = true;  
  5.         updateList(true);  
  6.     } else {  
  7.         mExpandList.onRefreshComplete();  
  8.     }  
  9. }  

一般来说我们会开另一个线程去获取数据,所以这儿会加上一个判断,如果已经在获取数据了,就onRefreshComplete(),就是将下拉收起;否则就去开新线程取数据,取完记得也要onRefreshComplete()哦!


二、上拉加载

如果你不想再费时间去自己写一个上拉加载,不妨试一下PullToRefresh自带的上拉效果哦!

PullToRefresh本身支持下拉刷新和上拉刷新,所以我们只需要将上拉刷新改成上拉

你可能感兴趣的:(源码,android,pulltorefresh,PullTo)