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

时间: 2016-01-24

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

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

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选择图片或拍照图片上传到服务器

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

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图片选择的两种方式

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实现拍照、选择图片并裁剪图片功能

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

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)

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实现本地图片选择及预览缩放效果

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

微信小程序实现图片选择并预览功能

本文实例为大家分享了微信小程序实现图片选择并预览的具体代码,供大家参考,具体内容如下 (一).功能说明 做的是一个意见反馈,用户发表意见和上传图片,限制了最多只能上传三张图片. 其他要点:textarea使用,底部保存按钮固定 (二).小程序接口说明 wx.chooseLocation(Object object) 从本地相册选择图片或使用相机拍照. (三).效果图 效果如下: (四).代码展示 WXML页面: <view class="wrap"> <view cl

ie8本地图片上传预览示例代码

复制代码 代码如下: imgpath= getRealPath(fileId): document.getElementById("divSBTP").style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='scale',src=\""+ imgpath + "\")";//使用滤镜效果 func

input type=file 选择图片并且实现预览效果的实例

通过<input />标签,给它指定type类型为file,可提供文件上传: accept:可选择上传类型,如:只要传图片,且不限制图片格式,为image/*: multiple:规定是否可以选择多个文件: 规定只可上传图片,且可以选择多个文件 <input type="file" accept="image/*" multiple="multiple"/> 当然,直接一个input type=file 只能选择上传的文件

微信小程序选择图片和放大预览图片功能

视频中,老师也是看着官方文档,为学生们讲解,微信提供了系统的方法来选择图片. wx.chooseImage({}) 此方法是用来选择图片的方法,具体使用如下: data: { avatarUrl:null }, 首先在数据中定义接收数据的变量,然后调用方法选择图片,将图片显示出来. bindViewTap:function(){ var that = this; wx.chooseImage({ // 设置最多可以选择的图片张数,默认9,如果我们设置了多张,那么接收时//就不在是单个变量了, c

Android实现仿Windows7图片预览窗格效果

本实例将显示类似于windows7提供的图片预览窗格效果,单击任意一张图片,可以在右侧显示该图片的预览效果. 效果如图所示: 具体实现方法: res/layout/main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orie

模拟QQ心情图片上传预览示例

出于安全性能的考虑,目前js端不支持获取本地图片进行预览,正好在做一款类似于QQ心情的发布框,找了不少jquery插件,没几个能满足需求,因此自己使用SWFuplad来实现这个图片上传预览. 先粘上以下插件,在别的图片上传功能说不定各位能用的上. 1.jQuery File Upload Demo地址:http://blueimp.github.io/jQuery-File-Upload/ 优点是使用jquery进行图片的异步上传,可控性好,可根据自己的需求任意定制: 缺点是在IE9等一些浏览器

Vue.js 2.0 移动端拍照压缩图片上传预览功能

在学习和使用Vue.js 2.0 的过程中遇到不少不一样的地方,本来移动端开发H5应用,准备将mui框架和Vue.js+vue-router+vuex 全家桶结合起来使用,但是在拍照上传的实现过程中遇到了无法调用plus的H5+接口的问题,所以最后拍照上传功能还是使用input file方式里解决的.但是内心还是不甘心的,由于项目进度推进,迭代版本,所以不得不放弃,后续可能我将此功能使用调用H5+接口实现. 首先我来讲我实现这个拍照预览压缩上传的思路,准确的说应该是拍照或选择图片压缩之后预览及上

JS实现图片上传预览功能

废话不多说了,直接给大家贴js代码了,具体代码如下所示: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title></title> </head> <body&g

js实现图片上传预览原理分析

目前网上有很多支持图片上传时进行预览的插件,功能完备,界面优雅,使用起来也很方便.一直以来也就只是用用,没有想过这些插件背后的实现原理.趁着今天有点时间,也来学习学习. 追根溯源 设想 一开始,按照我的思路,预览可能是这么来实现的.本地选中一张图片,嵌入html的同时会显示图片的本地的绝对路径,然后通过js简单的进行设置,应该就可以实现预览效果了. 但是实际上,目前只有低版本的IE浏览器才能实现这么个效果.究其原因是浏览器厂商为了进一步强化安全,限制了file标签直接读取本地路径的能力,在HTM