详解android写一个选择图片的示例代码

可以达到的效果

  • 第一个图片的位置放照相机,点击打开照相机
  • 其余的是显示全部存储的图片,点击一次是查看大图,长按则是每张图片出现一个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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

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

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

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

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

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

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

  • 详解android写一个选择图片的示例代码

    可以达到的效果 第一个图片的位置放照相机,点击打开照相机 其余的是显示全部存储的图片,点击一次是查看大图,长按则是每张图片出现一个checkBox,可以进行选择 下面是实例效果图 MainActivity 类 public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener, ImageAdapter

  • 详解Android封装一个全局的BaseActivity

    1.前言 对于一个Android开发者来说,每一个页面都继承一个单独的系统Activity,有时候会带来很多不必要的困扰.比如:每一个页面会有重复的代码,阅读起来麻烦:每一次写新的页面功能总要打开原来的页面代码拷贝一部分过来:有时候代码调试排查问题也不方便等等. 如果你的项目里面没有将Activity都继承自一个自己封装的BaseActivity.或者针对自己封装的BaseActivity觉得还不够完善的,这篇博客可能会对你有帮助! 2.特点 封装:将所有Activity都用到的一部分代码封装到

  • 用ES6的class模仿Vue写一个双向绑定的示例代码

    本文介绍了用ES6的class模仿Vue写一个双向绑定的示例代码,分享给大家,具体如下: 最终效果如下: 构造器(constructor) 构造一个TinyVue对象,包含基本的el,data,methods class TinyVue{ constructor({el, data, methods}){ this.$data = data this.$el = document.querySelector(el) this.$methods = methods // 初始化 this._com

  • 详解Nginx如何配置Web服务器的示例代码

    概述 今天主要分享怎么将NGINX配置作为Web服务器,并包括以下部分: 设置虚拟服务器 配置位置 使用变量 返回特定状态码 重写HTTP响应 在高层次上,将NGINX配置作为Web服务器有一些问题需要了解,定义它处理哪些URL以及如何处理这些URL上的资源的HTTP请求. 在较低层次上,配置定义了一组控制对特定域或IP地址的请求的处理的虚拟服务器. 用于HTTP流量的每个虚拟服务器定义了称为位置的特殊配置实例,它们控制特定URI集合的处理. 每个位置定义了自己的映射到此位置的请求发生的情况.

  • Java实现手写一个线程池的示例代码

    目录 概述 线程池框架设计 代码实现 阻塞队列的实现 线程池消费端实现 获取任务超时设计 拒绝策略设计 概述 线程池技术想必大家都不陌生把,相信在平时的工作中没有少用,而且这也是面试频率非常高的一个知识点,那么大家知道它的实现原理和细节吗?如果直接去看jdk源码的话,可能有一定的难度,那么我们可以先通过手写一个简单的线程池框架,去掌握线程池的基本原理后,再去看jdk的线程池源码就会相对容易,而且不容易忘记. 线程池框架设计 我们都知道,线程资源的创建和销毁并不是没有代价的,甚至开销是非常高的.同

  • 详解Java读取Jar中资源文件及示例代码

    详解Java读取Jar中资源文件及实现代码 直接上代码,文章的注释部分说的比较清楚,大家可以参考下, 工具类源代码: ResourceLoadFromJarUtil.java 实现代码: import java.io.IOException; import java.io.InputStream; import java.net.JarURLConnection; import java.net.MalformedURLException; import java.net.URL; import

  • 详解Android应用开发--MP3音乐播放器代码实现(一)

    需求1:将内存卡中的MP3音乐读取出来并显示到列表当中 1.从数据库中查询所有音乐数据,保存到List集合当中,List当中存放的是Mp3Info对象 2.迭代List集合,把每一个Mp3Info对象的所有属性,保存到Map对象当中 3.定义一个List集合,把Map对象添加到List集合当中 4.通过定义一个SimpleAdpter,调用setAdpter方法,将数据显示到列表当中 /** * 用于从数据库中查询歌曲的信息,保存在List当中 * * @return */ public Lis

  • 详解Android.activity销毁流程的工作原理

    继续我们的源码解析,上一篇文章我们介绍了Activity的启动流程,一个典型的场景就是Activity a 启动了一个Activity b,他们的生命周期回调方法是: onPause(a) –> onCreate(b) –> onStart(b) –> onResume(b) –> onStop(a) 而我们根据源码也验证了这样的生命周期调用序列,那么Activity的销毁流程呢?它的生命周期的调用顺序又是这样的呢? 这里我们我做一个简单的demo,让一个Activity a启动A

  • 详解android 通过uri获取bitmap图片并压缩

    详解android 通过uri获取bitmap图片并压缩 很多人在调用图库选择图片时会在onActivityResult中用Media.getBitmap来获取返回的图片,如下: Uri mImageCaptureUri = data.getData(); Bitmap photoBmp = null; if (mImageCaptureUri != null) { photoBmp = MediaStore.Images.Media.getBitmap(ac.getContentResolve

  • 详解Android中图片的三级缓存及实例

    详解Android中图片的三级缓存及实例 为什么要使用三级缓存 如今的 Android App 经常会需要网络交互,通过网络获取图片是再正常不过的事了 假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量.在当前的状况下,对于非wifi用户来说,流量还是很贵的,一个很耗流量的应用,其用户数量级肯定要受到影响 特别是,当我们想要重复浏览一些图片时,如果每一次浏览都需要通过网络获取,流量的浪费可想而知 所以提出三级缓存策略,通过网络.本地.内存三级缓存图片,来减少不必要的网络交互,避免浪费流量

随机推荐