Android 图片选择详解及实例代码

 Android 图片选择

可以达到的效果:

1.第一个图片的位置放照相机,点击打开照相机

2.其余的是显示全部存储的图片,点击一次是查看大图,长按则是每张图片出现一个checkBox,可以进行选择

下面是实例效果图

MainActivity 类

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener, ImageAdapter.OnImageCheckListener, View.OnClickListener {

  private static final int CAMERA_CODE = 12;
  List<File> fileList = new ArrayList<>();
  ImageAdapter adapter;

  GridView gvImage;
  TextView tvFinish;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
    //弹出对话框,加载数据
    loadData();
  }

  private void initView() {
    gvImage = (GridView) findViewById(R.id.gv_image);
    tvFinish = (TextView) findViewById(R.id.tv_finish);

    adapter = new ImageAdapter(this, fileList);
    adapter.setOnImageCheckListener(this);
    gvImage.setAdapter(adapter);
    gvImage.setOnItemClickListener(this);
    gvImage.setOnItemLongClickListener(this);

    tvFinish.setOnClickListener(this);
  }

  private ProgressDialog showProgressDialog() {
    //弹出对话框
    ProgressDialog dialog = new ProgressDialog(this);
    dialog.setTitle("提示");
    dialog.setMessage("正在加载图片,请稍等。。。");
    dialog.show();
    return dialog;
  }

  private void loadData() {
    final ProgressDialog dialog = showProgressDialog();
    //开启线程
    new Thread() {
      @Override
      public void run() {
        super.run();
        //递归
        //从sd卡中获取所有图片
        getFile(Environment.getExternalStorageDirectory());
        runOnUiThread(new Runnable() {
          @Override
          public void run() {
            dialog.dismiss();
            adapter.notifyDataSetChanged();
          }
        });
      }
    }.start();
  }

  public void getFile(File dir) {
    //1. 获取子目录
    File[] files = dir.listFiles();
    if (files == null)
      return;
    //集合或者数组去点for
    for (File file : files) {
      if (file.isDirectory())
        getFile(file);
      else {
        //加载图片
        if (file.getName().endsWith(".png") || file.getName().endsWith(".jpg")) {
          fileList.add(file);
        }
      }

    }
  }

  File cameraFile;

  //点击
  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    if (position == 0) {
      //getAbsolutePath返回的路径是没有"/"
      cameraFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/" + System.currentTimeMillis() + ".png");
      //打开照相机
      Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
      //照相机需要带数据
      intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile));
      startActivityForResult(intent, CAMERA_CODE);
    } else {
      //打开大图
      File file = fileList.get(position - 1);
      //带数据跳转到现实大图
      Intent intent = new Intent(this, ShowBigImage.class);
      intent.putExtra("file", file);
      startActivity(intent);
    }
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.e("TAG", resultCode + "---------------------");
    if (requestCode == CAMERA_CODE && resultCode == RESULT_OK) {
      Log.e("TAG", (cameraFile.exists()) + "");
      fileList.add(0, cameraFile);
      adapter.notifyDataSetChanged();
    }
  }

  //长按
  @Override
  public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
    if (position == 0)
      return false;
    else {
      adapter.open(position);
    }
    return true;
  }

  @Override
  public void onImageCheck(boolean b) {
    //b代表 适配器中 有没有勾选的值
    tvFinish.setEnabled(b);

  }

  @Override
  public void onClick(View v) {
    //需要知道有哪些数据被选中
    //不能使用泛型,ArrayList才实现了序列化,List没有实现
    ArrayList<File> resultList = new ArrayList<>();
    //通过适配器中的 为true的 选中的项来加载file
    SparseBooleanArray booleanArray = adapter.getBooleanArray();
    for (int i = 0; i < booleanArray.size(); i++) {
      boolean isCheck = booleanArray.get(booleanArray.keyAt(i));
      if (isCheck) {
        int position = booleanArray.keyAt(i);
        resultList.add(fileList.get(position - 1));
      }
    }
    Intent intent = new Intent();
    intent.putExtra("list", resultList);
    //返回数据
    setResult(RESULT_OK, intent);
    finish();
  }
}

ImageAdapter 类

public class ImageAdapter extends ListItemAdapter<File> {

  private boolean select = false;

  public void open(int posisiont) {
    select = true;
    booleanArray.put(posisiont, true);
    if (onImageCheckListener != null)
      onImageCheckListener.onImageCheck(true);
    this.notifyDataSetChanged();
  }

  public void close() {
    select = false;
    booleanArray.clear();
    notifyDataSetChanged();
  }

  //position
  //HashMap<Integer, Boolean> map = new HashMap<>();

  private SparseBooleanArray booleanArray = new SparseBooleanArray();

  public SparseBooleanArray getBooleanArray() {
    return booleanArray;
  }

  public ImageAdapter(Context context, List<File> list) {
    super(context, list);
  }

  @Override
  public int getCount() {
    //多出来的就是照相机
    return super.getCount() + 1;
  }

  //  @Override
//  public View getView(int position, View convertView, ViewGroup parent) {
//    if (convertView == null) {
//      ImageView iv = new ImageView(mContext);
//      iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
//      iv.setBackgroundColor(Color.argb(0xFF, 0x07, 0x05, 0x18));
//      int width = mContext.getResources().getDisplayMetrics().widthPixels / 3 - 2;
//      GridView.LayoutParams params = new GridView.LayoutParams(width, width);
//      iv.setPadding(2, 2, 2, 2);
//      iv.setLayoutParams(params);
//      convertView = iv;
//    }
//    ImageView iv = (ImageView) convertView;
//    if (position == 0) {
//      //照相机
//      iv.setImageResource(R.mipmap.camera);
//    } else {
//      iv.setImageURI(Uri.fromFile(getItem(position - 1)));
//    }
//    return convertView;
//  }
  @Override
  public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
      convertView = View.inflate(mContext, R.layout.item_image, null);
      holder = new ViewHolder(convertView);
      convertView.setTag(holder);
    } else {
      holder = (ViewHolder) convertView.getTag();
    }
    if (position == 0) {
      holder.image.setImageResource(R.mipmap.camera);
      holder.checkBox.setVisibility(View.GONE);
    } else {
      holder.image.setImageURI(Uri.fromFile(getItem(position - 1)));
      if (select) {
        holder.checkBox.setVisibility(View.VISIBLE);
        //当前的需不需要勾选呢
        //null
        Boolean b = booleanArray.get(position);
        if (b == null || b == false) {
          holder.checkBox.setChecked(false);
        } else {
          holder.checkBox.setChecked(true);
        }
        //item点击和布局冲突
        holder.checkBox.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            Boolean b = booleanArray.get(position);
            if (b == null || b == false)
              b = true;
            else
              b = false;
            booleanArray.put(position, b);
            //判断所有的boolean,如果已经没有一个true 关闭
            for (int i = 0; i < booleanArray.size(); i++) { //4-true 0==false
              //两个值 key -- > 3 4
              // 0 1 2 3 4 5
              boolean isChecked = booleanArray.get(booleanArray.keyAt(i));
              Log.e("TAG", "----" + isChecked);
              Log.e("TAG", booleanArray.toString());
              if (isChecked) {
                //有被勾选的值
                if (onImageCheckListener != null)
                  onImageCheckListener.onImageCheck(true);
                return;
              }
            }
            if (onImageCheckListener != null)
              onImageCheckListener.onImageCheck(false);
            //没有被勾选的值了
            //关闭
            close();
          }
        });
      } else {
        holder.checkBox.setVisibility(View.GONE);
      }
      //不能使用onCheck
//      holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
//        @Override
//        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//          booleanArray.put(position, isChecked);
//        }
//      });
    }
    return convertView;
  }

  //回调方法。
  //写在需要执行方法的地方
  //他实现 在需要返回的地方
  public interface OnImageCheckListener {
    public void onImageCheck(boolean b);
  }

  private OnImageCheckListener onImageCheckListener;

  //alt+insert

  public void setOnImageCheckListener(OnImageCheckListener onImageCheckListener) {
    this.onImageCheckListener = onImageCheckListener;
  }

  class ViewHolder {
    ImageView image;
    CheckBox checkBox;

    public ViewHolder(View convertView) {
      image = (ImageView) convertView.findViewById(R.id.iv_image);
      int width = mContext.getResources().getDisplayMetrics().widthPixels / 3 - 2;
      RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, width);
      image.setLayoutParams(params);
      checkBox = (CheckBox) convertView.findViewById(R.id.cb_check);
    }

  }
}

ListItemAdapter类

//也可以用 extends 来限制一个泛型的父类
//在类的后面定义一个泛型
public abstract class ListItemAdapter<T> extends BaseAdapter {

  protected Context mContext;
  protected List<T> mList;

  //必须要有上下文,数据
  //List<File> List<String>
  public ListItemAdapter(Context context, List<T> list) {
    mContext = context;
    mList = list;
  }

  //适配器去加载一个List
  public void setList(List<T> list) {
    this.mList = list;
    notifyDataSetChanged();
  }

  @Override
  public int getCount() {
    return mList == null ? 0 : mList.size();
  }

  @Override
  public T getItem(int position) {
    return mList.get(position);
  }

  @Override
  public long getItemId(int position) {
    return position;
  }
}

ShowBigImage 类

public class ShowBigImage extends AppCompatActivity {

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ImageView iv = new ImageView(this);
    File file = (File) getIntent().getSerializableExtra("file");
    iv.setImageURI(Uri.fromFile(file));
    setContentView(iv);
  }
}

main_xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/activity_main"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  tools:context="com.example.administrator.imageselector.MainActivity">

  <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/colorPrimary">

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerInParent="true"
      android:text="选取图片"
      android:textColor="@android:color/white"
      android:textSize="18sp" />

    <TextView
      android:id="@+id/tv_finish"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentRight="true"
      android:layout_centerVertical="true"
      android:layout_marginRight="10dp"
      android:enabled="false"
      android:text="完成"
      android:textColor="@color/textenable" />
  </RelativeLayout>

  <GridView
    android:id="@+id/gv_image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:horizontalSpacing="2dp"
    android:numColumns="3"
    android:verticalSpacing="2dp" />
</LinearLayout>

item_image.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="#03030a">

  <ImageView
    android:id="@+id/iv_image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp"
    android:scaleType="centerCrop"
    android:src="@mipmap/camera" />

  <CheckBox
    android:id="@+id/cb_check"
    android:button="@null"
    android:layout_width="20dp"
    android:layout_height="20dp"
    android:background="@drawable/cb_selector"
    android:layout_alignParentRight="true"
    android:layout_margin="10dp"
    />

</RelativeLayout>

res下color文件夹下的textenable.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="@android:color/white" android:state_enabled="true" />
  <item android:color="@android:color/darker_gray" android:state_enabled="false" />
</selector>

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2016-12-23

浅谈谈Android 图片选择器

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

Android 高仿QQ图片选择器

当做一款APP,需要选择本地图片时,首先考虑的无疑是系统相册,但是Android手机五花八门,再者手机像素的提升,大图无法返回等异常因数,导致适配机型比较困难,微信.QQ都相继的在自己的APP里集成了图片选择功能,放弃了系统提供的图片选择器,这里仿造QQ做了一个本地图片选择器,PS:之前有人说"仿"写成"防"了,今儿特意注意了下,求不错. 先上一张效果图,无图无真相啊~~~ 实现的效果大概是这样的: 1.单选:跳转到本地图片选择文件夹,选择文件夹后,进入到该文件夹下

Android图片选择器ImageEditContainer

1. 简介 本次demo中一共封装了两个组件:ImageEditButton 和 ImageEditContainer.其中ImageEditContainer 是在 ImageEditButton,两个组件可单独使用. 在demo中,实现了 图片选择(拍照+本地),裁剪,压缩,保存本地 以及对已选择图片的删除操作(如果有修改需求,也可以使用对应方法进行操作,该方法已添加): 还有就是 针对 6.0权限的处理问题,本次使用了第三方库 rxpermissions 进行权限的处理. 2.项目主目录结

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

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

Android自定义View实现多图片选择控件

前言 相信很多朋友在开发中都会遇到图片上传的情况,尤其是多图上传,最经典的莫过于微信的图片选择了.所有很多情况下会使用到多图选择,所以就有了这篇文章,今天抽点时间写了个控件.  •支持自定义选择图片的样式  •支持设置图片选择数量  •支持图片预览,删除  •支持图片拍照 先来看看效果 实现分析 假如不定义控件,我们要实现这样一个功能,无非是写个GridView在item点击的时候去显示图片进行选择,在返回界面的时候进行GridView的数据刷新.我们把这些逻辑写在我们自定义的GridView中

Android图片选择器 丰富的配置选项

最近也是刚好项目用到,于是就动手写了一个Android 图片选择器的库.支持图库多选/单选/图片裁剪/拍照/自定义图片加载库,极大程度的简化使用. 截图 优点 1.通过实现ImageLoader接口,可以实现自定义图片加载器的功能.例如可以用Glide.Picasso.ImageLoader,暂不支持Fresco,因为SimpleDraweeView本身并不属于ImageView.当然,也可用相同的思路来实现. 2.可配置的ImgSelConfig.方便进行扩展. 3.简化使用 项目地址:htt

分享实现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实现底部图片选择Dialog

业务需要选择弹出对话框,然后点击选择图片.网上已经有了很多,不过感觉写的有点乱.自己这里总结一下,有需要开发者可以按照如下步骤直接使用即可. 1.效果图如下 点击选择照相后,弹出如下选择对话框: 2. Dialog实现 布局 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:la

Android仿微信图片选择器

很多项目要用到图片选择控件,每次都要写一大堆逻辑.于是基于图片选择组件(PhotoPicker)封装了一个控件PhotoUploadView.方便简易,一键集成,几句代码就可以添加类似微信的图片选择控件了.下面介绍一下该控件有些什么特点以及怎么使用.先看图: 效果如上图,点击加号弹出选择框,目前提供了两种形式,一个如图所见的PopupWindow,另一个是MaterialDialog,选择拍照或者从图库获取,从图库获取后就进入图二,选择完之后就图三或图四这里因为很多项目需要不一样,所以特别封装了

Android仿微信图片选择器ImageSelector使用详解

今天给大家介绍一个仿微信的图片选择器:ImageSelector.ImageSelector支持图片的单选.限数量的多选和不限数量的多选.支持图片预览和图片文件夹的切换.在上一篇文章 <Android 实现一个仿微信的图片选择器> 中我介绍了ImageSelector的实现思路和分析了它的核心代码,有兴趣的同学可以看一下.完整的代码放在了GitHub,欢迎大家下载和使用.本篇文章为大家介绍ImageSelector的具体使用方式. 先上效果图: 1.引入依赖 在Project的build.gr

Android仿微信图片点击全屏效果

废话不多说,先看下效果: 先是微信的 再是模仿的 先说下实现原理,再一步步分析 这里总共有2个Activity一个就是主页,一个就是显示我们图片效果的页面,参数通过Intent传送,素材内容均来自网络,(感谢聪明的蘑菇) 图片都是Glide异步下的,下的,下的重要的事情说三次,然后就是用动画做放大操作然后显示出来了(并没有做下载原图的实现,反正也是一样 下载下来Set上去而且动画都不需要更简便). OK,我们来看分析下 obj,目录下分别创建了2个对象,一个用来使用来处理显示页面的图片尺寸信息以

Android仿微信图片上传带加号且超过最大数隐藏功能

1.仿照微信空间上传图片,显示图片数量以及超过最大,上传按钮隐藏功能 2.上效果图 3.上代码,主要是Adapter类 /** * Created by zhangyinlei on 2018/3/2 0002. */ public class AlbumSelectedShowAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private static int TYPE_ADD = 0;//添加图片 privat

Android ImageSelector微信图片选择器

前言 现在绝大多数的App都上传图片的功能,比如设置用户头像.聊天发送图片.发表动态.论坛帖子等.上传图片需要先从选择手机中选择要上传的图片,所以图片选择器在App中是很常见的组件,一般的手机都会自带一个图片选择器.不过很多App并不喜欢用手机自带的选择器,而是自己实现一个图片选择器. 比如微信的图片选择器就做的很好.没办法,谁让微信这么强大,我不超抄袭你,但是,我可以模仿你. 效果图 是不是和真的一样,哈哈,不过,作者的唯一缺陷就是没有提供拍照,唉,有一点遗憾,但是,这个就够用了! 思路 1.

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

好了下面进入正题,我们先看一下实现效果吧: 下面来介绍一下代码: 本思路就是: 1.先到手机中扫描jpeg和png的图片 2.获取导图片的路径和图片的父路径名也就是文件夹名 3.将图片路径和文件夹名分别添加导数据源中 4.数据源有了就是显示了,文件夹显示是利用的popwindow,而图片显示则是GridView 看一下具体代码: 首先开启一个线程去扫描图片 /** * 利用ContentProvider扫描手机中的图片,此方法在运行在子线程中 完成图片的扫描,最终获得jpg最多的那个文件夹 */

Android仿微信图片点击浏览的效果

本篇我们来做一个类似于微信的图片点击浏览的效果,点击小图图片后会放大至全屏显示,且中间有一个2D平滑过渡的效果. 思路如下: 首先,从图片缩略界面跳转到图片详情页面,应该是从一个Activity跳转到另外一个Activity,应该图片详情页面也有很多操作,用View或者Dialog不是很好.所以现在难点就是,如何使得前一个界面的ImageView在另外一个界面做缩放切割动画. 其次,一般缩略界面的ImageView的是正方形的,并且是CENTER_CROP缩放属性的.CENTER_CROP属性会

Android仿微信朋友圈图片选择器

最近做开发需要解决一个模仿微信朋友圈附加图片的功能,具体要求如下: (1)从手机中最多选择3张图片,可拍照上传: (2)选择的图片可以点击移除然后再添加新图片: (3)可以在手机包含图片的各个文件夹中随意选择等. 本博客主要实现的是以上功能,其他诸如主界面布局.各种控件添加和提交功能等旨在说明问题,只做了简单处理,重点在图片选择添加部分.该功能的实现主要引用了一个图片加载的开源框架universal-image-loader. 其中截图如下: 为了不过于冗余,过滤了部分布局文件和资源文件,在这里

Android仿微信发朋友圈浏览图片效果

先看一下效果吧: 下面就来说一下具体怎么实现的: 实现思路 1.首先我们要获取数据源,数据源就是我们的每条说说(包括姓名.标题.图片数组) 2.自定义适配器(ListView嵌套着GridView) 3.图片点击浏览图片(Fragment+ViewPager) 具体实现 1.初始化数据源,设置适配器,看一下代码: public class MyActivity extends Activity { /*图片显示列表*/ private ListView listView; /*图片URL数组*/