Android开发listview异步加载图片

释放双眼,带上耳机,听听看~!

一般,我们使用listview加载图片时,有很多的jar包已经封装的很好,我们只需要知道怎么使用就可以,比如常用的imageLoader,使用非常的方便。但是,我们也要知道自己怎么用listview异步加载图片。昨天,在网上找了资料,自己总算是做出来了。

1.新建一个普通的listview,每个item里存放一个imageview和textView,然后做好一个适配器adapter。

adapter的getview()和普通的listview一样,编写很简单。

public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = null;
TextView textView = null;
if (convertView == null) {
convertView = layoutInflater.inflate(listviewItem, null); // 获取条目的view对象
imageView = (ImageView) convertView.findViewById(R.id.imageView);
textView = (TextView) convertView.findViewById(R.id.textView);
convertView.setTag(new DataWrapper(imageView, textView));
} else {
DataWrapper dataWrapper = (DataWrapper) convertView.getTag();
imageView = dataWrapper.imageView;
textView = dataWrapper.textView;
imageView.setTag(position);
}
Contact contact = data.get(position);
textView.setText(contact.name);
//=====初始化时加载图片
if (isInit==false){
asyncImageLoad(imageView, contact.image);
}
retu

在getView里,asyncImageLoad(imageView, contact.image);是用来异步加载图片的,每次调用getView()时,通过传递imageview和图片的网络地址,开启一个异步任务,去网络下载图片,下载后,首先存入缓存,然后存入sd卡,下载完成后显示在listview上,下载调用时会先从软引用寻找图片,用的话直接显示图片,如果没有,则从sd卡找图片,有的话显示图片,如果没有,则进行网络请求。

2.编写异步请求的代码。

private void asyncImageLoad(ImageView imageView, String path) {
if (imageCache.containsKey(path)) {
SoftReference<Drawable> softReference = imageCache.get(path);
Drawable drawable = softReference.get();
if (drawable != null) {
imageView.setImageDrawable(drawable);
Log.e("Test_path",""+path);
return;
}
}
Log.e("Test_path2",""+path);
AsyncImageTask asyncImageTask = new AsyncImageTask(imageView);
asyncImageTask.execute(path);
}

这其中用到一个异步加载的类AsyncImageTask,当每次请求网络图片时,获得图片后,会把图片存入软引用。

 private final class AsyncImageTask extends AsyncTask<String, Integer, Uri> {
private ImageView imageView;
private String imageUrl;
public AsyncImageTask(ImageView imageView) {
this.imageView = imageView;
}
protected Uri doInBackground(String... params) {// 子线程中执行的
try {
imageUrl=params[0];
return ContactService.getImage(params[0], cache);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Uri result) {// 运行在主线程
if (result != null && imageView != null)imageView.setImageURI(result);Drawable drawable =imageView.getDrawable();
imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
}
}

在doInBackground()内开启了线程,进行网络请求。

public static Uri getImage(String path, File cacheDir) throws Exception{// path -> MD5 ->32字符串.jpg
File localFile = new File(cacheDir, MD5.getMD5(path)+ path.substring(path.lastIndexOf(".")));
if(localFile.exists()){
return Uri.fromFile(localFile);
}else{
Log.e("Test_MD5",""+path);
HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode() == 200){
FileOutputStream outStream = new FileOutputStream(localFile);
InputStream inputStream = conn.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;
while( (len = inputStream.read(buffer)) != -1){
outStream.write(buffer, 0, len);
}
inputStream.close();
outStream.close();
return Uri.fromFile(localFile);
}
}
return null;
}

getImage()内用get()去请求图片,然后获得图片后,存入sd卡,然后返回图片存入文件的URI。

然后,AsyncImageTask的onPostExecute()获得URI,然后通过imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));设置图片。

这样就完成了图片的异步加载。这时滑动listview,会发现滑动有卡顿,所以可以设置listview的滑动监听。

mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
switch (scrollState) {
case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:// 滑动停止
isInit=true;
for (; start_index < end_index; start_index++) {
ImageView imageView = (ImageView) mListView.findViewWithTag(start_index);
Contact contact = ContactAdapter.this.data.get(start_index);
if (imageView!=null){
asyncImageLoad(imageView, contact.image);
}else {
Log.e("Test2",""+imageView);
}
}
break;
default:
break;
}
}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
start_index = firstVisibleItem;
end_index = firstVisibleItem + visibleItemCount;
}
});

其中ImageView imageView = (ImageView) mListView.findViewWithTag(start_index);是因为在getview()内我设置了imageview的Tag.imageView.setTag(position);然后在空闲的状态下调用异步加载图片。

这样就完成了异步加载,与滑动不加载的功能。

人已赞赏
Android文章

android 访问https服务器

2020-3-13 11:01:40

Android文章

android工作注意事项

2020-3-13 14:26:34

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索