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

前言:根据前几篇的阶段性成果(下拉刷新、异步加载),将其集成,就成了这篇文章,这篇文章代码量比较大,对于异步加载的部分,除了更改了getView()里绑定部分的代码,其它的都没有动,所以异步刷新里的代码我就不往里贴了,只贴MainActivity.java的代码,主要看看主程序是如何实现异步加载图片和下拉刷新的。

相关文章:(这篇文章是集这几篇文章之成果,大家可能要先看看这几篇文章,然后再回来看这篇,才可能能看懂,要不然就只能下下来代码自己研究了)

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

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

《异步加载图片(一)》

《异步加载图片(二)》


其它相关文章 

1、《List控件使用--SimpleAdapter使用详解(一)》

2、《List控件使用--SimpleAdapter使用详解(二)》

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

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

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

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

7、《PullToRefresh使用详解(五)--下拉刷新的ScrollView》


效果图:

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

PullToRefresh使用详解(三)--实现异步加载的下拉刷新列表_第1张图片   PullToRefresh使用详解(三)--实现异步加载的下拉刷新列表_第2张图片 

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

PullToRefresh使用详解(三)--实现异步加载的下拉刷新列表_第3张图片   PullToRefresh使用详解(三)--实现异步加载的下拉刷新列表_第4张图片   PullToRefresh使用详解(三)--实现异步加载的下拉刷新列表_第5张图片

 一、MainActivity.java

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

 

package com.example.try_simpleadapter_new;
/**
 * 完成与服务器通信的下拉刷新
 * @author harvic
 */
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;


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

import android.os.AsyncTask;
import android.os.Bundle;
import android.text.format.DateUtils;
import android.util.Log;
import android.widget.ListView;
import android.app.ListActivity;

public class MainActivity extends ListActivity{

	private String serverIP="http://222.195.151.19";
	private List<ImageAndText> mData;
	private PullToRefreshListView mPullRefreshListView;
	ImageAndTextListAdapter adapter=null;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);	
		
		mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);

		//设定下拉监听函数
		mPullRefreshListView.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);

				// Update the LastUpdatedLabel
				refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);

				Log.d("msg","this=="+this);
				// Do work to refresh the list here.
				new GetDataTask().execute();
				
			}
		});

		mPullRefreshListView.setMode(Mode.PULL_FROM_END);// 设置底部下拉刷新模式
		//传参生成适配器
		mData = getData();
		ListView actualListView = mPullRefreshListView.getRefreshableView();
		adapter = new ImageAndTextListAdapter(this,mData,actualListView);
		
		// 设置适配器
		actualListView.setAdapter(adapter);		
	}
	
	private List<ImageAndText> getData() {
		//创建默认的httpClient实例.  
				DefaultHttpClient httpclient = new DefaultHttpClient(); 
		        HttpResponse response = null;
		        HttpEntity entity = null;
		        
		        StringBuilder builder = new StringBuilder();  
		        JSONArray jsonArray = null;  
		        
				List<ImageAndText> list = new ArrayList<ImageAndText>();				
		                                                             
		        try{
		        	 // 创建httpost.访问本地服务器网址  
		        	HttpPost httpost = new HttpPost(serverIP+"/try_an_server/index.php");   
		            
		        	 //构造POST方法的{name:value} 参数对
		        	 List <NameValuePair>  vps = new ArrayList <NameValuePair>();   
		             //将参数传入post方法中
		             vps.add(new BasicNameValuePair("action", "insert"));  
		             vps.add(new BasicNameValuePair("name", "进去了"));
					             
					httpost.setEntity(new UrlEncodedFormEntity(vps, HTTP.UTF_8));
					response = httpclient.execute(httpost);  //执行
					
					if (response.getEntity() != null) {            	
						//如果服务器端JSON没写对,这句是会出异常,是执行不过去的
					 BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));  
					 String s = reader.readLine();
					 for (; s != null; s = reader.readLine()) { 
					     builder.append(s);  
					 }  
					 Log.i("msg","builder.toString = "+ builder.toString()); 
					 
					 jsonArray = new JSONArray(builder.toString());  
					 for (int i = 0; i < jsonArray.length(); i++) {
						 if(jsonArray.getJSONObject(i).getInt("id")==1){
							 String name=jsonArray.getJSONObject(i).getString("name");
							 String info=jsonArray.getJSONObject(i).getString("info");
							 String PicName=jsonArray.getJSONObject(i).getString("photo");
							 String picURL=serverIP+"/try_an_server/"+PicName+".jpg";
							 
							ImageAndText item=new ImageAndText(picURL,name,info);
							list.add(item);
						 }
					 }
					}
		        } catch (Exception e) {
					e.printStackTrace();
				} finally {
					try {
						 if (entity != null)
						 {
							httpclient.getConnectionManager().shutdown();//关闭连接
							//这两种释放连接的方法都可以
						 }
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}  
				}

			return list;	
    
	}
	
	
	
	private class GetDataTask extends AsyncTask<Void, Void, ImageAndText> {

		//后台处理部分
		@Override
		protected ImageAndText doInBackground(Void... params) {
			// Simulates a background job.
			ImageAndText item = null;
			try {
				item = new ImageAndText(serverIP+"/try_an_server/xizang.jpg", "sss", "ssss");				
			} catch (Exception e) {
				// TODO: handle exception
				setTitle("map出错了");
			}
			
			return item;
		}

		//这里是对刷新的响应,可以利用addFirst()和addLast()函数将新加的内容加到LISTView中
		//根据AsyncTask的原理,onPostExecute里的result的值就是doInBackground()的返回值
		@Override
		protected void onPostExecute(ImageAndText result) {
			//在头部增加新添内容
			
			try {
				mData.add(result);
				
				//通知程序数据集已经改变,如果不做通知,那么将不会刷新mListItems的集合
				adapter.notifyDataSetChanged();
				adapter.loadImage();
				// Call onRefreshComplete when the list has been refreshed.
				mPullRefreshListView.onRefreshComplete();
			} catch (Exception e) {
				// TODO: handle exception
				setTitle(e.getMessage());
			}

			super.onPostExecute(result);
		}
	}
	

}

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

		mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);

		//设定下拉监听函数
		mPullRefreshListView.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);

				// Update the LastUpdatedLabel
				refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);

				Log.d("msg","this=="+this);
				// Do work to refresh the list here.
				new GetDataTask().execute();
				
			}
		});

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

	private class GetDataTask extends AsyncTask<Void, Void, ImageAndText> {
		//后台处理部分
		@Override
		protected ImageAndText doInBackground(Void... params) {
			// Simulates a background job.
			ImageAndText item = null;
			try {
				item = new ImageAndText(serverIP+"/try_an_server/xizang.jpg", "sss", "ssss");				
			} catch (Exception e) {
				// TODO: handle exception
				setTitle("map出错了");
			}
			
			return item;
		}

		//这里是对刷新的响应,可以利用addFirst()和addLast()函数将新加的内容加到LISTView中
		//根据AsyncTask的原理,onPostExecute里的result的值就是doInBackground()的返回值
		@Override
		protected void onPostExecute(ImageAndText result) {
			//在头部增加新添内容
			
			try {
				mData.add(result);
				
				//通知程序数据集已经改变,如果不做通知,那么将不会刷新mListItems的集合
				adapter.notifyDataSetChanged();
				adapter.loadImage();
				// Call onRefreshComplete when the list has been refreshed.
				mPullRefreshListView.onRefreshComplete();
			} catch (Exception e) {
				// TODO: handle exception
				setTitle(e.getMessage());
			}

			super.onPostExecute(result);
		}
	}

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

mPullRefreshListView.setMode(Mode.PULL_FROM_END);// 设置底部下拉刷新模式
//传参生成适配器
mData = getData();
ListView actualListView = mPullRefreshListView.getRefreshableView();
adapter = new ImageAndTextListAdapter(this,mData,actualListView);

// 设置适配器
actualListView.setAdapter(adapter);		

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

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

 

 源码地址:http://download.csdn.net/detail/harvic880925/6804007(不要分,仅供分享)

 请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/17789617

你可能感兴趣的:(PullToRefresh使用详解(三)--实现异步加载的下拉刷新列表)