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;//课程学习人数 } }
相关文章推荐
- android的IPC机制
- 手机点击QQ直接跳转
- Android地图开发 安全码生成
- Android Calendar的学习与运用
- 让android定时关机的实现方法
- android Gson的使用
- 再谈ArcGIS Runtime SDK for Android中文标注无法显示的问题
- Android之RxJava(一)
- android-Creating a Content Provider(2)
- Android知识总结:Universal-Imageloader学习笔记1 基本功能与配置
- Android系统源码下载过程
- android中用Spannable在TextView中设置超链接、颜色、字体
- Android环境的搭建
- Android播放视频
- Android Studio手把手——帮你了解Gradle
- android---logcat
- Android的绘图机制学习---自定义View
- Android使用AlarmManager全局定时器实现定时更换壁纸
- android-Creating a Content Provider
- 【分享】Android Studio专用文件转换工具:把ANSI文件批量另存为无BOM的UTF-8文件