您的位置:首页 > 理论基础 > 计算机网络

自己定制ListView,上拉刷新和下拉刷新,加载网络图片,并且添加缓存机制。

2015-12-18 14:37 609 查看
package com.lixu.listviewrefresh;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

import com.lixu.listviewrefresh.Loadnetimage.OnLoadnetimageListener;
import com.lixu.listviewrefresh.MyRefreshListview.OnRefreshListener;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
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 static final String KEY_IMAGE = "image_key";
private static final String KEY_TEXT = "text_key";

private static final String CACHE_KEY_IMAGE = "cache_image_key";
private static final String CACHE_KEY_TEXT = "cache_text_key";
// 原始数据
private ArrayList<HashMap<String, Object>> data;
// 缓存队列
private ArrayList<HashMap<String, Object>> cache;

private ArrayAdapter<String> mMyAdapter;

private MyRefreshListview lv;

private Activity activity;
private Random random = new Random();
// 图片网络地址
private String[] image_urls = { "http://img0.bdstatic.com/img/image/shouye/mxh007.jpg",
"http://f.hiphotos.baidu.com/image/h%3D360/sign=1c9a50843ec79f3d90e1e2368aa0cdbc/f636afc379310a5566becb8fb24543a982261036.jpg",
"http://h.hiphotos.baidu.com/image/h%3D360/sign=04ef437b0b23dd543e73a16ee108b3df/50da81cb39dbb6fd9d9ada390b24ab18962b37ef.jpg",
"http://b.hiphotos.baidu.com/image/h%3D360/sign=e91921f7c1fdfc03fa78e5bee43e87a9/8b82b9014a90f60352684b4e3b12b31bb151eddb.jpg",
"http://g.hiphotos.baidu.com/image/h%3D360/sign=a2540bdbf21f3a2945c8d3c8a925bce3/fd039245d688d43fa9943bf77f1ed21b0ef43bf1.jpg",
"http://p4.so.qhimg.com/bdr/_240_/t01d4c378e7c6bfbe69.jpg",
"http://p0.so.qhimg.com/bdr/_240_/t0160872a7d33df5735.jpg",
"http://p3.so.qhimg.com/bdr/_240_/t01473a131702c357dd.jpg" };

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

activity = this;

data = new ArrayList<HashMap<String, Object>>();
cache = new ArrayList<HashMap<String, Object>>();
// 添加初始数据
for (int i = 0; i < 30; i++) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put(KEY_IMAGE, BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
map.put(KEY_TEXT, i);
data.add(map);
}

lv = (MyRefreshListview) findViewById(R.id.listview);

mMyAdapter = new MyAdapter(this, -1);

lv.setAdapter(mMyAdapter);

lv.setOnRefreshListener(new OnRefreshListener() {

@Override
public void ontop() {
// 随机加入一张图片
adddata(image_urls[random.nextInt(8)]);

}

@Override
public void onbuttom() {
// 没有设置缓存机制
new MyAsyncTaskBottom(image_urls[random.nextInt(8)]).execute();
}
});
}

private class MyAdapter extends ArrayAdapter<String> {
private LayoutInflater flater;
private Context context;

public MyAdapter(Context context, int resource) {

super(context, resource);
this.context = context;
flater = LayoutInflater.from(context);

}

@Override
public int getCount() {
return data.size();
}

@SuppressLint("InflateParams")
@Override
public View getView(int position, View convertView, ViewGroup parent) {

if (convertView == null)
convertView = flater.inflate(R.layout.list, null);

ImageView iv = (ImageView) convertView.findViewById(R.id.image);

iv.setImageBitmap((Bitmap) data.get(position).get(KEY_IMAGE));

TextView tv = (TextView) convertView.findViewById(R.id.text);

tv.setText(position + "原始数据");

return convertView;
}

}

private class MyAsyncTaskTop extends AsyncTask {
private ProgressDialog pd;
@SuppressWarnings("unused")
private String url;

public MyAsyncTaskTop(String url) {
this.url = url;
}

@Override
protected void onPreExecute() {
// 设置加载进度条
pd = new ProgressDialog(activity);
pd.setProgressStyle(pd.STYLE_HORIZONTAL);
pd.setMessage("正在加载。。。");
pd.show();
}

@Override
protected Object doInBackground(Object... params) {

try {
// 回调加载网络的类Loadnetimage
Loadnetimage mLoadnetimage = new Loadnetimage();

mLoadnetimage.SetLoadnetimageListener(new OnLoadnetimageListener() {

@SuppressWarnings("unchecked")
@Override
public void LoadnetimageListener(int count, int total) {
publishProgress(count, total);

}
});
// 获取网络图片
Bitmap bitmap = mLoadnetimage.loadRawDataFromURL(url);
// 每次将图片和对应的地址放入HashMap
HashMap<String, Object> map = new HashMap<String, Object>();
// 将新加载图片放入缓存
map.put(CACHE_KEY_IMAGE, bitmap);
map.put(CACHE_KEY_TEXT, url);

cache.add(map);

return bitmap;
} catch (Exception e) {
e.printStackTrace();
}

return null;

}

@Override
protected void onPostExecute(Object result) {
addtop(result);
pd.dismiss();

}

// 更新进度条
@Override
protected void onProgressUpdate(Object... values) {
int count = (Integer) values[0];
int total = (Integer) values[1];

pd.setMax(total);
pd.setProgress(count);

}

}

@SuppressWarnings("unused")
private class MyAsyncTaskBottom extends AsyncTask {
private ProgressDialog pd;
private String url;

public MyAsyncTaskBottom(String url) {
this.url = url;
}

@Override
protected void onPreExecute() {
// 设置进度条
pd = new ProgressDialog(activity);
// 样式
pd.setProgressStyle(pd.STYLE_HORIZONTAL);
pd.setMessage("正在加载。。。");
pd.show();

}

@Override
protected Object doInBackground(Object... params) {
// 回调加载网络的类Loadnetimage
Loadnetimage mLoadnetimage = new Loadnetimage();
// 获取网络图片
Bitmap bitmap;
try {
bitmap = mLoadnetimage.loadRawDataFromURL(url);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

@Override
protected void onPostExecute(Object result) {
addbottom(result);
pd.dismiss();

}

}

private void adddata(String url) {
// 设置缓存机制
Log.e("", "开始添加");

for (int i = 0; i < cache.size(); i++) {

HashMap<String, Object> map = cache.get(i);
// 判断图片地址一样则载入缓存
if (url.equals(map.get(CACHE_KEY_TEXT))) {
Bitmap bitmap = (Bitmap) map.get(CACHE_KEY_IMAGE);
addtop(bitmap);
Log.e("", "载入缓存");

return;
}

}
// 否则从网络新加载
Log.e("", "最新加载");
new MyAsyncTaskTop(url).execute();

}

private void addtop(Object result) {

// 新加载图片放入原始数据
HashMap<String, Object> map = new HashMap<String, Object>();
map.put(KEY_IMAGE, result);
map.put(KEY_TEXT, data.size() + 1);

data.add(0, map);

mMyAdapter.notifyDataSetChanged();
}

private void addbottom(Object result) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put(KEY_IMAGE, result);
map.put(KEY_TEXT, data.size() + 1);

data.add(map);

mMyAdapter.notifyDataSetChanged();
// 添加数据后自动滚动到底部
lv.setSelection(ListView.FOCUS_DOWN);

}

}


package com.lixu.listviewrefresh;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class Loadnetimage {
// 设置回调机制

private OnLoadnetimageListener mOnLoadnetimageListener;

public Loadnetimage() {

}

public interface OnLoadnetimageListener {
public void LoadnetimageListener(int count, int total);
}

public void SetLoadnetimageListener(OnLoadnetimageListener l) {
mOnLoadnetimageListener = l;
}

public Bitmap loadRawDataFromURL(String u) throws Exception {

URL url = new URL(u);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置请求的一些常用的参数
conn.setReadTimeout(30000);
conn.setConnectTimeout(30000);
conn.setDoInput(true);
conn.connect();
// 获取图片总数
int total = conn.getContentLength();

InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 缓存2KB
final int BUFFER_SIZE = 2 * 1024;
final int EOF = -1;

int count = 0;

int c;
byte[] buf = new byte[BUFFER_SIZE];

while (true) {
c = bis.read(buf);
if (c == EOF)
break;
// 每次累加到现在为止我们下载了多少数据,以便于后面计算已经下载的数据占了总数量的百分比
count = count + c;
// 发布最新的数据,更新随后的进度条显示进度使用
if (mOnLoadnetimageListener != null)
mOnLoadnetimageListener.LoadnetimageListener(count, total);
baos.write(buf, 0, c);
}

conn.disconnect();
is.close();

byte[] data = baos.toByteArray();
baos.flush();

Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

return bitmap;
}

}


package com.lixu.listviewrefresh;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;

public class MyRefreshListview extends ListView {
private OnRefreshListener mOnRefreshListener;
private Context context;
private int firstVisibleItem, visibleItemCount, totalItemCount;

public MyRefreshListview(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;

}

public interface OnRefreshListener {

public void ontop();

public void onbuttom();
}

public void setOnRefreshListener(OnRefreshListener l) {
this.mOnRefreshListener = l;
// 这个方法可以解决当listview中初始没有数据的时候滑动来加载数据
final GestureDetector mGestureDetector = new GestureDetector(context,
new GestureDetector.SimpleOnGestureListener() {

// velocityY表示触摸停止点Y到触摸起始点Y的速度值 当两点距离值为负时,速度值也为负所以:
// >0表示从上往下拉
// <0表示从下往上拉
public boolean onFling(android.view.MotionEvent e1, android.view.MotionEvent e2, float velocityX,
float velocityY) {
if (velocityY > 0) {

// 滑动到顶部时添加
if (firstVisibleItem == 0) {

mOnRefreshListener.ontop();

}

}
if (velocityY < 0) {
// 滑动到底部时添加
if ((firstVisibleItem + visibleItemCount) == totalItemCount) {

mOnRefreshListener.onbuttom();

}
}

return super.onFling(e1, e2, velocityX, velocityY);
};

});
this.setOnTouchListener(new OnTouchListener() {
// 将触摸事件交给GestureDetector来处理
@Override
public boolean onTouch(View v, MotionEvent event) {

return mGestureDetector.onTouchEvent(event);
}
});

this.setOnScrollListener(new OnScrollListener() {

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {

}

@Override
public void onScroll(AbsListView view, int fvi, int vic, int tic) {

firstVisibleItem = fvi;
visibleItemCount = vic;
totalItemCount = tic;

}
});

}

}


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.lixu.listviewrefresh.MainActivity" >

<com.lixu.listviewrefresh.MyRefreshListview
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</RelativeLayout>


<?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="vertical" >

<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</LinearLayout>


运行效果图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: