您的位置:首页 > 移动开发 > Android开发

Android中listView中用于下载、显示图片

2015-11-28 19:52 465 查看
缓存—>SD卡—>网络

ImageLoader

package com.example.jack.myapplication.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.util.LruCache;
import android.widget.ImageView;

import com.example.jack.myapplication.R;
import com.example.jack.myapplication.consts.MyHttpURL;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
* 用于下载、显示图片
* Created by ding on 2015/10/26.
*/
public class ImageLoader {

//缓存
private LruCache<String, Bitmap> mCaches;
private String bitmapFileName ;
//构造方法
public ImageLoader() {
//获取最大可用内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 4;
mCaches = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
//在每次存入缓存时调用,存入图片大小
return value.getByteCount();
}
};
}

//将图片写入缓存
public void addBitmapToCache(String bitmapFileName, Bitmap bitmap) {
//先判断bitmap是否为空
if (getBitmapFromCache(bitmapFileName) == null) {
mCaches.put(bitmapFileName, bitmap);
}
}

//根据url获得缓存的图片
public Bitmap getBitmapFromCache(String bitmapFileName) {
if(bitmapFileName!=null){
return mCaches.get(bitmapFileName);
}else {
return null ;
}
}

/**
* 通过url获得图片
*
* @param  urlString
* @return
*/
public Bitmap getBitmapFromURL(String urlString) {

if(urlString.equals(MyHttpURL.IP+null)||urlString.equals(MyHttpURL.IP)){
return null ;
}

Bitmap bitmap;
InputStream is = null;
URL url;
try {
url = new URL(urlString);

HttpURLConnection connection = (HttpURLConnection) url.openConnection();
Log.i("getBitmapFromURL参数url为:",urlString);

InputStream ins = connection.getInputStream();

//缓冲流
is = new BufferedInputStream(ins);

//将is转化为bitmap
bitmap = BitmapFactory.decodeStream(is);
//添加网络中下载的bitmap到缓存和本地sd卡
addBitmapToCache(urlString,bitmap);
addBitmapToFile(urlString,bitmap);
//关闭连接
connection.disconnect();
return bitmap;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}

File dir = null;
/**
* 将图片文件写入文件
* @param url
* @param bitmap
*/
public void addBitmapToFile(String url,Bitmap bitmap){
//Environment.getExternalStorageState()方法用于获取SDCard的状态,如果手机装有SDCard,
//并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){

FileOutputStream fos = null ;
//创建根目录文件对象
if(dir == null){
dir = new File("/mnt/sdcard/test/");
}

//如果根目录文件对象不存在
if (!dir.exists()) {
dir.mkdirs();
}
File bitmapFile = null ;
//创建图片文件对象
if(bitmapFile == null){
bitmapFile = new File("/mnt/sdcard/test/" +
url.substring(url.lastIndexOf("/") + 1));
}
//如果图片文件对象不存在,则创建新的文件
if (!bitmapFile.exists()) {
try {
bitmapFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

try {
if(fos == null ){
//得到文件输出流
fos = new FileOutputStream(bitmapFile);
}
//将图片文件写进文件中
bitmap.compress(Bitmap.CompressFormat.PNG , 100 , fos);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

/**
* 通过AsyncTask显示图片:从缓存中找--->从本地文件中找--->从网络中找
* @param imageView
* @param imageUrl
*/
public void showImageByAsyncTask(ImageView imageView, String imageUrl) {

int i = 0 ;
//根据url构建图片文件名
bitmapFileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
//从缓存中取名为url的图片
Bitmap bitmap = getBitmapFromCache(bitmapFileName);
Log.i("提示:","从缓存中得到的图片"+bitmap);
//如果缓存中没有,则先从本地文件中找
if (bitmap == null) {

Log.i("提示:","SD卡中图片的文件名"+bitmap);
//创建根目录文件对象
if(dir == null){
dir = new File("/mnt/sdcard/test/");
}
//得到文件列表
File[] cacheFiles = dir.listFiles();
Log.i("提示:","文件列表为:"+cacheFiles);
Log.i("提示:","文件列表的大小:"+cacheFiles.length);

if (cacheFiles != null) {

//逐一查找
for (; i < cacheFiles.length; i++) {
//如果文件列表中存在与图片文件名相同的文件,则跳出for循环
if (bitmapFileName.equals(cacheFiles[i].getName())) {
break;//跳出for循环
}
}
//如果i < cacheFiles.length,说明存在图片文件
if (i < cacheFiles.length) {
imageView.setImageBitmap(BitmapFactory.decodeFile("/mnt/sdcard/test/" + bitmapFileName));
Log.i("提示:", "显示的图片从SD卡中来");
//将SD卡的图片放到缓存中
addBitmapToCache(bitmapFileName, BitmapFactory.decodeFile("/mnt/sdcard/test/" + bitmapFileName));
return;//跳出方法
}else{
//如果文件列表都没有,则从网络中找
LessonsIconAsyncTask task = new LessonsIconAsyncTask(imageView);
//执行task
task.execute(imageUrl);
}
}
//文件夹都不存在,则图片也不存在
else{
//如果文件列表都没有,则从网络中找
LessonsIconAsyncTask task = new LessonsIconAsyncTask(imageView);
//执行task
task.execute(imageUrl);
}
} else {
//缓存中存在,则直接显示图片
imageView.setImageBitmap(bitmap);
Log.i("提示:","显示的图片从缓存中来");
}
}

/**
* 自定义的AsyncTask,传进的类型、返回过程、返回的类型
*/
private class LessonsIconAsyncTask extends AsyncTask<String, Void, Bitmap> {
private ImageView mImageView ;
//构造方法
private LessonsIconAsyncTask(ImageView imageView) {
mImageView = imageView ;
}

@Override
protected Bitmap doInBackground(String... params) {
//图片url
String url = params[0];
//从网络中获取图片
Bitmap bitmap = getBitmapFromURL(url);
//如果从网络中获得的图片不为空
if (bitmap != null) {  //  1、将图片写入缓存 2、将图片写入文件
//将图片以url为标志写入缓存
addBitmapToCache(bitmapFileName, bitmap);
//将图片写入文件
addBitmapToFile(bitmapFileName, bitmap);
}
return bitmap;
}

//上面doInBackground返回的bitmap在这里处理
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
//如果该imageView不为空且bitmap不为空
if (mImageView != null && bitmap != null) {
//imageView显示图片
mImageView.setImageBitmap(bitmap);
Log.i("提示:", "显示的图片从网络中来");
}else {
mImageView.setImageResource(R.mipmap.no);
Log.i("提示:", "显示的图片为默认图片");
}
}
}

}


LessonListAdapter

package com.example.jack.myapplication.adapter;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.example.jack.myapplication.R;
import com.example.jack.myapplication.entity.Lesson;
import com.example.jack.myapplication.utils.ImageLoader;

import java.util.List;

/**
* listView的适配器
* Created by ding on 2015/10/13.
*/
public class LessonListAdapter extends BaseAdapter {

//保存所有需要显示的图片的url地址
public String[] imageUrls;
//数据源:课程信息集合
List<Lesson> lessons;
//运行上下文
private Context context;
//视图容器
private LayoutInflater inflater;
//图片下载的工具类
private ImageLoader mImageLoader;

//构造方法
public LessonListAdapter(Context context, List<Lesson> lessons, ListView listView) {
//并设置上下文
this.context = context;
//创建视图容器
inflater = LayoutInflater.from(context);
//数据源
this.lessons = lessons;

imageUrls = new String[lessons.size()];
for (int i = 0; i < lessons.size(); i++) {
//将图片url保存到该数组里面
imageUrls[i] = lessons.get(i).getLIcon();
}
//初始化ImageLoader,加载显示图片的工具类,将listview传进去
mImageLoader = new ImageLoader();
}

// 在此适配器中所代表的数据集中的条目数
public int getCount() {
return lessons.size();
}

//获取数据集中与指定索引对应的  数据项
public Object getItem(int position) {
return lessons.get(position);
}

//取在列表中与指定索引对应的行id
public long getItemId(int position) {
return position;
}

/*
ListView Item设置  :获取一个在数据集中指定索引的视图来显示数据
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//控件集
ViewHolder holder = null;
//如果缓存convertView为空,则需要创建View
if (convertView == null) {
//实例化控件集
holder = new ViewHolder();
//获取list_item布局文件的视图  : 根据自定义的Item布局加载布局
convertView = inflater.inflate(R.layout.lesson_item, null);

//获取控件对象
holder.ivLessonIcon = (ImageView) convertView.findViewById(R.id.ivLessonIcon);
holder.tvLessonName = (TextView) convertView.findViewById(R.id.tvLessonName);
holder.tvLessonSectionNumber = (TextView) convertView.findViewById(R.id.tvLessonSectionNumber);

//将设置好的布局保存到缓存(convertView )中,并将其设置在Tag里,以便后面方便取出Tag
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Lesson lesson = (Lesson) getItem(position);

//图片url
String url = lesson.getLIcon();
Log.i("提示:", "图片url为:" + url);
//调用mImageLoader中的showImageByAsyncTask方法加载并显示图片
mImageLoader.showImageByAsyncTask(holder.ivLessonIcon, url);
holder.tvLessonName.setText(lesson.getLName());
holder.tvLessonSectionNumber.setText(lesson.getLCount() + " 人学习");

return convertView;
}

//自定义控件集合 :优化性能,按需填充并重新使用view来减少对象的创建。
class ViewHolder {
private ImageView ivLessonIcon;//课程图标
private TextView tvLessonName;//课程标题
private TextView tvLessonSectionNumber;//课程学习人数
}

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