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

时间:2022-03-19 08:58:45

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

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

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

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

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

下面来介绍一下代码:

 本思路就是:

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

看一下具体代码:

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/**
 * 利用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弹出事件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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);
  }
 });
 }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//设置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中删除和添加的操作,更新选择图片的数量,也就是下面这两段代码:

?
1
2
3
4
5
6
7
8
9
10
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);
?
1
2
3
4
5
6
7
8
9
10
11
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软件编程有所帮助。