前言
最近公司需要做一个类似微信那种选择头像和上传图片的功能,本想上github上找的,后来想了想,还是自己做一个,不仅方便以后用(毕竟自己写的修改起来也比较方便),还可以学到一些知识,废话少说,先看效果图:
(ps:大致的功能就这样,拍照功能就是拍了照片之后跳到剪切的页面,这里没有截出来,主要是为了压缩下gif图的大小)
现在来简单的介绍下有什么功能:
可根据传入的值控制是选择头像还是上传图片,大于1就是选择图片,等于1救是选择头像
可根据传入的值控制选择图片的数量,并且当选中的图片数量等于这个数量时,则其他没有被选中的图片变成不可选择
可选择不同文件夹下的图片
自定义ViewGroup显示选中的图片数,不同的数量显示的格式不一样(gif最后那一帧录制的不是很清楚),类似微信那种,1张,2张还是9张显示的格式不同
拍照剪切头像
大概下就是这么些,现在我们来说说实现的思路,主要分为几步
在子线程中读出sd卡下所有的文件夹下的图片,并且在RecyclerView中显示出来
RecyclerView采用多item布局方式,分开拍照和图片,主要是方便修改拍照的view,这里只是用图片显示
适配每个图片等宽度和高度为屏幕宽度等三分之一
底部采用PopupWindow显示出所有的图片所在的文件夹
如果是多选图片,则为每个view添加checkbox的选中监听,否则就调用系统的剪切图片功能,剪切完成之后显示出来
根据选中的图片数,展示不同的布局
好了,现在我们来看看代码
ImageSelectActivity
这个activity主要是用来显示从sd中读取出来的图片
package com.myimageselectcontainer;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.support.annotation.BoolRes;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
import com.myimageselectcontainer.adapter.ImageDirAdapter;
import com.myimageselectcontainer.adapter.MyAdapter;
import com.myimageselectcontainer.adapter.SpacesItemDecoration;
import com.myimageselectcontainer.bean.ImageBean;
import com.myimageselectcontainer.bean.ImageDirBean;
import com.myimageselectcontainer.click.OnChangeListener;
import com.myimageselectcontainer.click.OnImageDirItemListener;
import com.myimageselectcontainer.click.OnItemClickListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public class ImageSelectActivity extends AppCompatActivity implements OnItemClickListener,
OnChangeListener, View.OnClickListener, PopupWindow.OnDismissListener, OnImageDirItemListener {
private static final int PHOTO_REQUEST_CAMERA = 1;// 拍照
private static final int PHOTO_REQUEST_CUT = 2;// 结果
private ProgressDialog mProgressDialog;
/**
* 存储文件夹中的图片数量
*/
private int mPicsSize;
/**
* 扫描拿到所有的图片文件夹
*/
private List imageDirBeans = new ArrayList<>();
/**
* 图片数量
*/
private int totalCount = 0;
/**
* 临时的辅助类,用于防止同一个文件夹的多次扫描
*/
private HashSet mDirPaths = new HashSet<>();
/**
* 所有的图片
*/
private List mImages = new ArrayList<>();
/**
* 选中的图片集合
*/
private ArrayList mSelectImages = new ArrayList<>();
/**
* 最大的图片数
*/
private int maxImageCount = 9;
/**
* 屏幕高度
*/
private int mScreenHeight;
/**
* 用来存储选中的文件
*/
private File mSelectFile;
/**
* 用于显示全部文件夹
*/
private PopupWindow mPopupWindow;
/**
* 当PopupWindow显示或者消失时改变背景色
*/
private WindowManager.LayoutParams lp;
/**
* 拿到传过来的值,测试选择图片
*/
private int select;
/**
* 存储拍照和选中的图片
*/
private File file;
private MyThread mThread;
private ImageDirBean imageDirBean;
private ImageBean imageBean;
private RecyclerView rcyImageSelect;
private TextView tvImageCount;
private TextView tvImageDir;
private TextView tvConfirm;
private LinearLayout linearLayout;
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
mProgressDialog.dismiss();
//绑定数据
setData();
if (mThread != null && !mThread.isInterrupted()) {
mThread.isInterrupted();
}
}
};
private MyAdapter mAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_select);
select = getIntent().getIntExtra("select", 0);
maxImageCount = select;
rcyImageSelect = (RecyclerView) findViewById(R.id.rcyView_imageSelect);
tvImageCount = (TextView) findViewById(R.id.tv_imageCount);
tvImageDir = (TextView) findViewById(R.id.tv_imageDir);
tvConfirm = (TextView) findViewById(R.id.tv_confirm);
linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
mPopupWindow = new PopupWindow(this);
//获取屏幕高度,设给PopupWindow
DisplayMetrics outMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
mScreenHeight = outMetrics.heightPixels;
lp = getWindow().getAttributes();
rcyImageSelect.setLayoutManager(new GridLayoutManager(this, 3));
tvConfirm.setText("确定" + mSelectImages.size() + "/" + maxImageCount);
getImageList();
setImageDirData();
tvImageDir.setOnClickListener(this);
tvConfirm.setOnClickListener(this);
mPopupWindow.setOnDismissListener(this);
file = new File(Environment.getExternalStorageDirectory(), "temp.jpg");
}
private void setData() {
mAdapter = new MyAdapter(this, maxImageCount, mImages, this, this);
rcyImageSelect.setAdapter(mAdapter);
rcyImageSelect.addItemDecoration(new SpacesItemDecoration(2));
tvImageCount.setText(totalCount + "张");
}
//图片文件数据
private void setImageDirData() {
if (!imageDirBeans.isEmpty()) {
View contentView =