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软件编程有所帮助。

(0)

相关推荐

  • Android选择图片或拍照图片上传到服务器

    最近要搞一个项目,需要上传相册和拍照的图片,不负所望,终于完成了!  不过需要说明一下,其实网上很多教程拍照的图片,都是缩略图不是很清晰,所以需要在调用照相机的时候,事先生成一个地址,用于标识拍照的图片URI 具体上传代码: 1.选择图片和上传界面,包括上传完成和异常的回调监听 package com.spring.sky.image.upload; import java.util.HashMap; import java.util.Map; import android.app.Activi

  • Android实现本地图片选择及预览缩放效果

    在做项目时经常会遇到选择本地图片的需求,以前都是懒得写直接调用系统方法来选择图片,但是这样并不能实现多选效果,最近又遇到了,所以还是写一个demo好了,以后也方便使用.还是首先来看看效果: 显示的图片使用RecyclerView实现的,利用Glide来加载:下面弹出的图片文件夹效果是采用PopupWindow实现,这里比采用PopupWindow更方便,弹出显示的左边图片是这个文件夹里的第一张图片:选中的图片可以进行预览,使用网上一个大神写的来实现的:至于图片的获取是用ContentProvid

  • Android拍照或从图库选择图片并裁剪

    今天看<第一行代码>上面关于拍照和从相册选取图片那一部分,发现始终出不来效果,所以搜索其他资料学习一下相关知识,写一个简单的Demo. 一. 拍照选择图片 1.使用隐式Intent启动相机 //构建隐式Intent Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //调用系统相机 startActivityForResult(intent, 1); 2.处理相机拍照返回的结果 //用户点击了取消 if(data == n

  • 浅谈谈Android 图片选择器

    ImageSelector 简介 Android自定义相册,实现了拍照.图片选择(单选/多选).ImageLoader无绑定 任由开发者选择 https://github.com/YancyYe/ImageSelector Demo Download Apk 更新内容 UI重改 所有功能可配置 解决OOM情况 图片手动选择 支持汉语和英语 截图展示 使用说明 步骤一: 通过Gradle抓取 dependencies { compile 'com.yancy.imageselector:image

  • Android实现拍照、选择图片并裁剪图片功能

    一. 实现拍照.选择图片并裁剪图片效果 按照之前博客的风格,首先看下实现效果. 二. uCrop项目应用 想起之前看到的Yalantis/uCrop效果比较绚,但是研究源码之后发现在定制界面方面还是有一点的限制,于是在它的基础上做了修改Android-Crop,把定制界面独立出来,让用户去自由设置.下图为使用Android-Crop实现的模仿微信选择图片并裁剪Demo. 三. 实现思路 比较简单的选择设备图片裁剪,并将裁剪后的图片保存到指定路径: 调用系统拍照,将拍照图片保存在SD卡,然后裁剪图

  • Android仿微信选择图片和拍照功能

    本文实例为大家分享了 Android微信选择图片的具体代码,和微信拍照功能,供大家参考,具体内容如下 1.Android6.0系统,对于权限的使用都是需要申请,选择图片和拍照需要申请Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE这两个权限. if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageM

  • 分享实现Android图片选择的两种方式

    Android选择图片的两种方式: 第一种:单张选取 通过隐式启动activity,跳转到相册选择一张返回结果 关键代码如下: 发送请求: private static final int PICTURE = 10086; //requestcode Intent intent = new Intent(); if (Build.VERSION.SDK_INT < 19) {//因为Android SDK在4.4版本后图片action变化了 所以在这里先判断一下 intent.setAction

  • Android实现QQ图片说说照片选择效果

    本文实例为大家分享了Android实现QQ图片说说照片选择的具体代码,供大家参考,具体内容如下 效果展示 布局文件 布局是很简单的,一个GridView,直接上布局: layout/activity_add_photo.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/andr

  • android中写一个内部类来选择文件夹中指定的图片类型实例说明

    复制代码 代码如下: /**本类是用来选择文件夹中是.jpg类型的图片*/ private class JpgFileFilter implements FilenameFilter{ @Override public boolean accept(File dir, String filename) { // TODO Auto-generated method stub return filename.endsWith(".jpg"); } }

  • android完美实现 拍照 选择图片 剪裁等代码分享

    前言,版本兼容问题主要是由于4.4以前和4.4以后的Uri的格式不同所造成的错误 1.拍照 和选择图片   ①选择图片 intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); startActivityForResult(intent, GALLERY_REQUEST_CODE); ②拍照 intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE)

随机推荐