新建布局 item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="TextView" />
</LinearLayout>
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.listviewrefresh.MainActivity" >
<com.example.listviewrefresh.MyListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
Loader:
package com.example.listviewrefresh;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.util.Log;
public class Loader {
private OnUpdateProgessListener mOnUpdateProgessListener = null;
public void setOnUpdateProgessListener(OnUpdateProgessListener l) {
this.mOnUpdateProgessListener = l;
}
public interface OnUpdateProgessListener {
public void onUpdateProgress(int count, int total);
}
public byte[] loadRawDataFromURL(String u) throws Exception {
Log.d("下載數據...", u);
URL url = new URL(u);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 总的长度
int total = conn.getContentLength();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
final int BUFFER_SIZE = 2048;
final int EOF = -1;
int c;
// 下载的总数计数
int count = 0;
byte[] buf = new byte[BUFFER_SIZE];
while (true) {
c = bis.read(buf);
if (c == EOF)
break;
// 每次累加到现在为止我们下载了多少数据,以便于后面计算已经下载的数据占了总数量的百分比
count = count + c;
// 发布最新的数据,更新随后的进度条显示进度使用
if (mOnUpdateProgessListener != null)
mOnUpdateProgessListener.onUpdateProgress(count, total);
baos.write(buf, 0, c);
}
conn.disconnect();
is.close();
byte[] data = baos.toByteArray();
baos.flush();
Log.d("下載數據完畢", u);
return data;
}
}
MyListView:
package com.example.listviewrefresh;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.AbsListView;
import android.widget.ListView;
public class MyListView extends ListView {
private OnRefreshListener mOnRefreshListener;
public interface OnRefreshListener {
// 表示下拉见顶刷新回调的接口
public void onTop();
// 表示上拉见底刷新回调的接口
public void onBottom();
}
public void setOnRefreshListener(OnRefreshListener l) {
this.mOnRefreshListener = l;
this.setOnScrollListener(new OnScrollListener() {
private int firstVisibleItem, visibleItemCount, totalItemCount;
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
this.firstVisibleItem = firstVisibleItem;
this.visibleItemCount = visibleItemCount;
this.totalItemCount = totalItemCount;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
// 下拉见顶刷新事件,回调
if (firstVisibleItem == 0)
mOnRefreshListener.onTop();
// 上拉见底部的刷新事件,回调
boolean b = (firstVisibleItem + visibleItemCount) == totalItemCount;
if (b) {
mOnRefreshListener.onBottom();
}
}
}
});
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
MainActivity:
package com.example.listviewrefresh;
import java.util.ArrayList;
import java.util.HashMap;
import com.example.listviewrefresh.Loader.OnUpdateProgessListener;
import com.example.listviewrefresh.MyListView.OnRefreshListener;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
// 数据源
private ArrayList<HashMap<String, Object>> data;
private String CACHE_URL_KEY="cache_url_key",CACHE_BITMAP="cache_bitmap";
private ArrayList<HashMap<String, Object>> cache;
private String IMAGE_KEY = "image", TEXT_KEY = "text";
private ArrayAdapter adapter;
// 加载这个链接的图片资源
private String IMAGE_URL = "http://avatar.csdn.net/9/7/A/1_zhangphil.jpg";
private MyListView lv;
private Activity activity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
activity = this;
Resources res = getResources();
cache=new ArrayList<HashMap<String,Object>>();
data = new ArrayList<HashMap<String, Object>>();
for (int i = 0; i < 20; i++) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put(IMAGE_KEY,
BitmapFactory.decodeResource(res, R.drawable.ic_launcher));
map.put(TEXT_KEY, i);
data.add(map);
}
lv = (MyListView) findViewById(R.id.listView);
adapter = new MyAdapter(this, -1);
lv.setAdapter(adapter);
lv.setOnRefreshListener(new OnRefreshListener(){
@Override
public void onTop() {
loadNewData(IMAGE_URL);
}
@Override
public void onBottom() {
addBottom();
}});
}
private void loadNewData(String url){
Log.d("检查缓存...",url);
for(int i=0;i<cache.size();i++){
HashMap<String,Object> map=cache.get(i);
String u=map.get(CACHE_URL_KEY)+"";
if(url.equals(u)){
Log.d("发现缓存,直接取出来加载!",url);
Bitmap bmp=(Bitmap) map.get(CACHE_BITMAP);
addTop(bmp);
return;
}
}
Log.d("没有发现缓存,开启线程下载",url);
new AddTopAsyncTask().execute(url);
}
private class MyAdapter extends ArrayAdapter {
private LayoutInflater mLayoutInflater;
public MyAdapter(Context context, int resource) {
super(context, resource);
mLayoutInflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = mLayoutInflater.inflate(R.layout.item, null);
ImageView image = (ImageView) convertView
.findViewById(R.id.imageView);
TextView text = (TextView) convertView.findViewById(R.id.textView);
HashMap<String, Object> map = getItem(position);
image.setImageBitmap((Bitmap) map.get(IMAGE_KEY));
text.setText(map.get(TEXT_KEY) + "");
return convertView;
}
@Override
public HashMap<String, Object> getItem(int position) {
return data.get(position);
}
@Override
public int getCount() {
return data.size();
}
}
private void addTop(Bitmap obj) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put(IMAGE_KEY, obj);
map.put(TEXT_KEY, data.size());
data.add(0, map);
adapter.notifyDataSetChanged();
}
private class AddTopAsyncTask extends AsyncTask<String,Integer,Bitmap> {
private ProgressDialog pd;
@Override
protected void onPreExecute() {
pd = new ProgressDialog(activity);
pd.setMessage("请稍候,正在加载。。。");
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.show();
}
@Override
protected Bitmap doInBackground(String... params) {
String url=params[0];
try {
Loader loader=new Loader();
loader.setOnUpdateProgessListener(new OnUpdateProgessListener(){
@Override
public void onUpdateProgress(int count, int total) {
publishProgress(count,total);
}});
byte[] bytes=loader.loadRawDataFromURL(url);
Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0,bytes.length);
//将加载的数据添加到缓存队列中
HashMap<String,Object> map=new HashMap<String,Object>();
map.put(CACHE_URL_KEY, url);
map.put(CACHE_BITMAP, bmp);
cache.add(map);
return bmp;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
int count = (Integer) values[0];
int total = (Integer) values[1];
pd.setMax(total);
pd.setProgress(count);
}
@Override
protected void onPostExecute(Bitmap result) {
pd.dismiss();
addTop(result);
}
}
// 底部刷新增加数据
private void addBottom() {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put(IMAGE_KEY, BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher));
map.put(TEXT_KEY, data.size());
data.add(map);
adapter.notifyDataSetChanged();
lv.setSelection(ListView.FOCUS_DOWN);
}
}