现在的位置: 首页 > 综合 > 正文

Android项目实战-ListView异步图片加载及压缩缓存

2013年08月21日 ⁄ 综合 ⁄ 共 9825字 ⁄ 字号 评论关闭

这回先讲一下ListView异步加载图片的问题,相关的文章很多,不过在这里我将加载、压缩下载、存储到SD卡等功能全部放上来,方便大家使用或者研究。

 

1.      ListView中的SimpleAdapter中的操作

大家在使用ListView显示复杂的页面时,我们都全重写一个SimpleAdapter,重写其中的getView方法来显示具体内容。相关的内容我们下篇文章再说,这里主要看下图片显示的代码。

01 //图片内容显示
02         if(!topic.getImage_value().equals("")){
03             vh.tl_ll_content_image.setVisibility(View.VISIBLE);
04             //加上标识,要不图片加载会变乱
05             vh.tl_img_content_image.setTag(topic.getTid());
06             vh.tl_img_content_image.setImageResource(R.drawable.default_image_load);
07             //新开异步加载图片
08             LoadingTopicImageAsyncTaskloadingTopicImageAsyncTask =
new LoadingTopicImageAsyncTask(vh.tl_img_content_image, topic,ctxContext,true,String.valueOf(topic.getTid()));
09             loadingTopicImageAsyncTask.execute();
10          }

·vh. tl_ll_content_image是我们在ListView中要显示相关图片的控件。Topic是我们通过getView取到的当前行的数据对象。Topic.getImage_value()中则是要显示的图片url地址,比如:http://www.huoban168.com/huoban/upload/topic/2012/02/weibo_1329196372_1112447.png。

 ·为图片控件加上setTag主要是防止图片混乱。

·LoadingTopicImageAsyncTask是我们新开一个异步,下载或者加载相关的图片的类。基本上主要的操作都在此类中进行。

 

2.      LoadingTopicImageAsyncTask类中的操作

001 packagehb.hbwb.asynctask;
002 importhb.hbwb.model.beans.Topic;
003 importhb.hbwb.tools.PicTool;
004 importhb.hbwb.var.PublicVariable;
005   
006 importandroid.app.Activity;
007 importandroid.app.Dialog;
008 importandroid.graphics.Bitmap;
009 importandroid.os.AsyncTask;
010 importandroid.view.View;
011 importandroid.view.View.OnClickListener;
012 importandroid.widget.ImageView;
013   
014 /**
015  * @name 异步加载图片
016  * @author zhang.yue
017  * @create_date 2011-12-15
018  * @last_edit_author
019  * @last_edit_date
020  * @remark
021  * @edit_remark
022  */
023 public classLoadingTopicImageAsyncTask
extends
024            AsyncTask<String, Integer,String> {
025 private ImageView imageView =
null;
026 private Topic topic =
null;
027 private Bitmap bt =
null;
028 private Activity activity;
029 private boolean
isClick = true;
030 private String tag =
"";
031   
032 /**
033  * 重写构造
034  *
035  * @paramheaderView
036  *            图像控件
037  * @paramtopic
038  * @paramactivity
039  * @paramisClick
040  *            是否可以点击放大
041  */
042 public LoadingTopicImageAsyncTask(ImageViewimageView, Topic topic,
043                     Activity activity, booleanisClick, String tag) {
044            super();
045            this.imageView = imageView;
046            this.topic = topic;
047            this.activity = activity;
048            this.isClick = isClick;
049            this.tag = tag;
050 }
051   
052 @Override
053 protected String doInBackground(String...params) {
054            // 添加如果是本地缓存的从本地读取...
055            bt =PublicVariable.allTopicImage.get(String.valueOf(topic.getTid()));
056            if
(bt == null) {
057                     // 图像获取并保存
058                     if
(topic.getImage_value().equals("")){
059                              bt =
null;
060                     }
else {
061                              bt =PicTool.ReturnBitMap(topic.getImage_value());
062                     }
063            }
064            if
(bt!=null) {                               
065                     if(bt.getWidth()>PublicVariable.TOPIC_IMAGE_SHOW-40
||bt.getHeight()>PublicVariable.TOPIC_IMAGE_SHOW_HEIGHT-40) {
066                              bt =PicTool.ChangeSizeBitMap(bt, PublicVariable.TOPIC_IMAGE_SHOW-40);
067                     }
068            }
069            return
null;
070 }
071   
072 @Override
073 protected
void
onPostExecute(String result) {
074            super.onPostExecute(result);
075            if
(imageView != null
&&topic !=
null && !tag.equals("")) {
076                     if(imageView.getTag().toString().equals(tag)) {
077                              if
(bt != null) {
078                                        if(isClick) {
079                                                 //点击大图效果
080                                                 imageView.setOnClickListener(newOnClickListener() {
081                                                          @Override
082                                                          publicvoid onClick(View v) {
083                                                                    ShowImageClickListener(bt,activity);
084                                                          }
085                                                 });
086                                        }
087                                        imageView.setImageBitmap(bt);
088                                        PublicVariable.allTopicImage.put(
089                                                          String.valueOf(topic.getTid()),bt);
// 保存到数组中
090                              }
091                     }
092            }
093 }
094   
095 /**
096  * 图片点击功能事件处理
097  *
098  * @parambt
099  * @paramactivity
100  */
101 public static
voidShowImageClickListener(Bitmap bt, Activity activity) {
102            Bitmap maxBt =PicTool.ChangeSizeBitMap(bt,
103                              PublicVariable.TOPIC_IMAGE_SHOW);
104            ImageView showImageView = newImageView(activity);
105            showImageView.setImageBitmap(maxBt);
106            //两个嵌套的TabHost中,必须使用activity.getParent()
107            //在首页中使用并无报错,全局使用
108            Dialog d = newDialog(activity.getParent(), hb.hbwb.R.style.no_back_title_dialog);
109            d.setContentView(showImageView);
110            d.setCanceledOnTouchOutside(true);
111            d.show();
112 }
113   
114 }

·PublicVariable.allTopicImage是我们写的一个HashMap,存储Bitmap的一个集合,如果在程序的运行过程中多次显示同一个图片即可直接从这里面取出Bitmap并显示,可以节省网上加载或者sd卡读取的步骤,键值是topic的tid,一个微博仅显示一张图片。

·如果上述的Bitmap集合中不存在图片的话,调用PicTool类中的ReturnBitMap返回SD卡上缓存的图片。

·如果图片超过我们规定的一个大小,那么调用PicTool类中的ChangeSizeBitMap方法。

·onPostExecute方法是线程执行完成后,我们将Bitmap对象给予Image图片控件并显示出来。在这里我们还添加了点击事件。

 

3.      ReturnBitMap解析

001 /**
002  * 返回图片文件用
003  *
004  * @paramurl
005  *            图片url地址
006  *@return
007  */
008 public static
Bitmap ReturnBitMap(String url) {
009            String imgName =StringTool.GetImageNameForUrl(url);
010            if
(imgName.equals("")) {
011                     return
null;
012            }
else {
013                     FileTool ft = newFileTool();
014                     String path =FileFinals.SDCARDROOT + File.separator + FileFinals.SDCARDIMAGEPATH;
015                     // 图片文件存在并且不是刷新的时候
016                     if
(ft.IsFileExist(imgName +FileFinals.IMAGE_SYSTEM_EXT, FileFinals.SDCARDIMAGEPATH)) {
017                              Bitmap bm =ReturnLocalBitMap(path + File.separator + imgName);
018                              if(bm==null){
019                                        returnReturnWebBitMap(url, imgName, path);
020                              }else{
021                                        returnbm;
022                               }
023                     }
else {
024                              // 先删除原有的
025                              returnReturnWebBitMap(url, imgName, path);
026                     }
027            }
028 }
029          
030   
031 /**
032  * 本地获取图片信息
033  *
034  * @parampath
035  *            图片路径
036  *@return bitmap对象
037  */
038 public static
Bitmap ReturnLocalBitMap(Stringpath) {
039            Bitmap bitmap =BitmapFactory.decodeFile(path +
".image");
040            return
bitmap;
041 }
042   
043 /**
044  * 抓取远程图片
045  *
046  * @paramurl
047  *            图片地址
048  * @paramimgName
049  *            图片名
050  * @parampath
051  *            地址
052  *@return
053  */
054 public static
Bitmap ReturnWebBitMap(Stringurl, String imgName, String path) {
055   
056            Bitmap bitmap =
null;
057            try
{
058                     // 图片大小判断操作
059                     InputStream size_is =HTMLTool.GetHttpConnection(url).getInputStream();
060                     BitmapFactory.Options op =new
BitmapFactory.Options();
061                     op.inJustDecodeBounds =true;
062                     @SuppressWarnings("unused")
063                     Bitmap size_bitmap =BitmapFactory.decodeStream(size_is,
null, op);
064                     op.inJustDecodeBounds =true;
// 仅获取宽高信息,不加载整个图片
065                     boolean
isop = false;
066                     int
size =PublicVariable.TOPIC_IMAGE_SHOW; // 设定获取的大小不能超过宽高
067                     int
bili = 0;
// 压缩比例
068                     BitmapFactory.Options op_new=
new BitmapFactory.Options();
069                     if(op.outWidth>op.outHeight){
070                              if
(op.outWidth> size) {
071                                        bili =op.outWidth / size;
072                                        isop =true;
073                              }
074                     }else{
075                              if
(op.outHeight> size) {
076                                        bili =op.outHeight / size;
077                                          
078                                        isop =true;
079                              }
080                     }
081                     
082                     // 根据比例判断
083                     if
(bili != 0) {
084                              if
(bili < 2) {
085                                        bili =
2;
086                              }else{
087                                  bili = bili*2-2;
088                              }
089                              if(bili%2!=0){
090                                        bili =bili+1;
091                              }
092                              op_new.inSampleSize= bili;
093                     }
else {
094                              isop =
false;
095                     }
096                     System.out.println(bili);
097                     size_bitmap =
null;
098                     size_is.close();
099   
100                     // 如果进行过压缩,加载处理后的图片,如果没有直接加载
101                     InputStream is =HTMLTool.GetHttpConnection(url).getInputStream();
102                     if
(isop) {
103                              op_new.inPreferredConfig= Bitmap.Config.ARGB_4444;
104                              op_new.inPurgeable=
true;
105                              op_new.inInputShareable=
true;
106                              bitmap =BitmapFactory.decodeStream(is,
null, op_new);
107                     }
else {
108                              bitmap =BitmapFactory.decodeStream(is);
109                     }
110                     
111   
112                     // 将图片写入到内存卡中,做为缓存,将来直接本地读取
113                     WriteBitmapToSdCard(FileFinals.SDCARDIMAGEPATH,path + File.separator + imgName, bitmap);
114   
115                     is.close();
116   
117

抱歉!评论已关闭.