欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android仿微信照片选择器实现预览查看图片

程序员文章站 2024-02-13 11:00:04
好了下面进入正题,我们先看一下实现效果吧: 下面来介绍一下代码:  本思路就是: 1.先到手机中扫描jpeg和png的图片 2...

好了下面进入正题,我们先看一下实现效果吧:

Android仿微信照片选择器实现预览查看图片

Android仿微信照片选择器实现预览查看图片

Android仿微信照片选择器实现预览查看图片

Android仿微信照片选择器实现预览查看图片

下面来介绍一下代码:

 本思路就是:

  • 1.先到手机中扫描jpeg和png的图片
  • 2.获取导图片的路径和图片的父路径名也就是文件夹名
  • 3.将图片路径和文件夹名分别添加导数据源中
  • 4.数据源有了就是显示了,文件夹显示是利用的popwindow,而图片显示则是gridview

看一下具体代码:

首先开启一个线程去扫描图片

/** 
 * 利用contentprovider扫描手机中的图片,此方法在运行在子线程中 完成图片的扫描,最终获得jpg最多的那个文件夹 
 */ 
 private void getimages() 
 { 
 if (!environment.getexternalstoragestate().equals( 
  environment.media_mounted)) 
 { 
  toast.maketext(this, "暂无外部存储", toast.length_short).show(); 
  return; 
 } 
 // 显示进度条 
 mprogressdialog = progressdialog.show(this, null, "正在加载..."); 
 
 new thread(new runnable() 
 { 
  @override 
  public void run() 
  { 
 
  string firstimage = null; 
 
  uri mimageuri = mediastore.images.media.external_content_uri; 
  contentresolver mcontentresolver = albumactivity.this 
   .getcontentresolver(); 
 
  // 只查询jpeg和png的图片 
  cursor mcursor = mcontentresolver.query(mimageuri, null, 
   mediastore.images.media.mime_type + "=? or " 
    + mediastore.images.media.mime_type + "=?", 
   new string[] { "image/jpeg", "image/png" }, 
   mediastore.images.media.date_modified); 
 
  log.e("tag", mcursor.getcount() + ""); 
  while (mcursor.movetonext()) 
  { 
   // 获取图片的路径 
   string path = mcursor.getstring(mcursor 
    .getcolumnindex(mediastore.images.media.data)); 
 
   log.e("tag", path); 
   // 拿到第一张图片的路径 
   if (firstimage == null) 
   firstimage = path; 
   // 获取该图片的父路径名 
   file parentfile = new file(path).getparentfile(); 
   if (parentfile == null) 
   continue; 
   string dirpath = parentfile.getabsolutepath(); 
   imagefloder imagefloder = null; 
   // 利用一个hashset防止多次扫描同一个文件夹(不加这个判断,图片多起来还是相当恐怖的~~) 
   if (mdirpaths.contains(dirpath)) 
   { 
   continue; 
   } else 
   { 
   mdirpaths.add(dirpath); 
   // 初始化imagefloder 
   imagefloder = new imagefloder(); 
   imagefloder.setdir(dirpath); 
   imagefloder.setfirstimagepath(path); 
   } 
 
   int picsize = parentfile.list(new filenamefilter() 
   { 
   @override 
   public boolean accept(file dir, string filename) 
   { 
    if (filename.endswith(".jpg") 
     || filename.endswith(".png") 
     || filename.endswith(".jpeg")) 
    return true; 
    return false; 
   } 
   }).length; 
   totalcount += picsize; 
 
   imagefloder.setcount(picsize); 
   mimagefloders.add(imagefloder); 
 
   if (picsize > mpicssize) 
   { 
   mpicssize = picsize; 
   mimgdir = parentfile; 
   } 
  } 
  mcursor.close(); 
 
  // 扫描完成,辅助的hashset也就可以释放内存了 
  mdirpaths = null; 
 
  // 通知handler扫描图片完成 
  mhandler.sendemptymessage(0x110); 
 
  } 
 }).start(); 
 
 }

代码很详细不多说
文件夹popwindow弹出事件

private void initevent() 
 { 
 /** 
  * 为底部的布局设置点击事件,弹出popupwindow 
  */ 
 mbottomly.setonclicklistener(new view.onclicklistener() 
 { 
  @override 
  public void onclick(view v) 
  { 
  mlistimagedirpopupwindow 
   .setanimationstyle(r.style.anim_popup_dir); 
  mlistimagedirpopupwindow.showasdropdown(mbottomly, 0, 0); 
 
  // 设置背景颜色变暗 
  windowmanager.layoutparams lp = getwindow().getattributes(); 
  lp.alpha = .3f; 
  getwindow().setattributes(lp); 
  } 
 }); 
 } 

最后是设置图片的点击事件

//设置imageview的点击事件 
 mimageview.setonclicklistener(new onclicklistener() 
 { 
  //选择,则将图片变暗,反之则反之 
  @override 
  public void onclick(view v) 
  { 
 
  // 已经选择过该图片 
  if (mselectedimage.contains(mdirpath + "/" + item)) 
  { 
   mselectedimage.remove(mdirpath + "/" + item); 
   mselect.setimageresource(r.drawable.picture_unselected); 
   mimageview.setcolorfilter(null); 
   list<imagebean> delete = new arraylist<imagebean>(); 
   for (imagebean im:bimp.tempselectbitmap){ 
   if (im.getpath().equals(mdirpath + "/" + item)){ 
    delete.add(im); 
   } 
   } 
   bimp.tempselectbitmap.removeall(delete); 
   message msg = new message(); 
   msg.what=0; 
   albumactivity.handler.sendmessage(msg); 
  } else 
  // 未选择该图片 
  { 
   if (bimp.tempselectbitmap.size()>8){ 
   toast.maketext(context,"超出可选图片数",toast.length_short).show(); 
   return; 
   } 
   else { 
   mselectedimage.add(mdirpath + "/" + item); 
   mselect.setimageresource(r.drawable.pictures_selected); 
   mimageview.setcolorfilter(color.parsecolor("#77000000")); 
   imagebean imagebean = new imagebean(); 
   imagebean.setpath(mdirpath + "/" + item); 
   try { 
    imagebean.setbitmap(bimp.revitionimagesize(mdirpath + "/" + item)); 
   } catch (ioexception e) { 
    e.printstacktrace(); 
   } 
   bimp.tempselectbitmap.add(imagebean); 
   message msg = new message(); 
   msg.what=0; 
   albumactivity.handler.sendmessage(msg); 
   } 
 
  } 
 
  } 

这里面为了配合之前的博客,我加入了选中图片和取消选中图片将图片在bimp.tempselectbitmap中删除和添加的操作,更新选择图片的数量,也就是下面这两段代码:

list<imagebean> delete = new arraylist<imagebean>(); 
   for (imagebean im:bimp.tempselectbitmap){ 
   if (im.getpath().equals(mdirpath + "/" + item)){ 
    delete.add(im); 
   } 
   } 
   bimp.tempselectbitmap.removeall(delete); 
   message msg = new message(); 
   msg.what=0; 
   albumactivity.handler.sendmessage(msg); 
imagebean imagebean = new imagebean(); 
   imagebean.setpath(mdirpath + "/" + item); 
   try { 
    imagebean.setbitmap(bimp.revitionimagesize(mdirpath + "/" + item)); 
   } catch (ioexception e) { 
    e.printstacktrace(); 
   } 
   bimp.tempselectbitmap.add(imagebean); 
   message msg = new message(); 
   msg.what=0; 
   albumactivity.handler.sendmessage(msg); 

这里有一点说明,就是我在写移除图片的时候遇到了一个错误,java concurrentmodificationexception异常,这个错误就是说当我们的vector,list或者arraylist中的数据源发生变化的时候,你再去操作这个list就会出现这个异常错误,解决办法是,遍历这个图片数组,比较路径是否相同(最好的办法是比较id是否相同),new 一个数组将相同的图片假如new的数组中,最后用之前的图片数组removeall来移除,这样就不会报异常错误了,当然我们new的数组肯定比我们之前的数组数据源少或者等同。

以上就是本文的全部内容,希望对大家学习android软件编程有所帮助。