android多图选择器demo
来源:互联网 发布:上瘾网络剧全集 编辑:程序博客网 时间:2024/05/17 04:42
本文是根据鸿祥大神的博客http://blog.csdn.net/lmj623565791/article/details/39943731进化而来,在大神的基础上更进一步封装拍照,防止oom,选择图片后回调。
效果如图所示,点击加号弹出dialog,可以选择从照相机拍照也可以选择从图库选择多张图片。
为了方变使用,封装了一个父类。在父类中进行dialog的点击事件响应并接收照相机的回调和多图选择后的回调,并对外提供两个接口,一个是选择单一图片的回调,一个是选择多图的回调。代码如下
public class SelectImageActivity extends AppCompatActivity{ protected CameraAlbumDialog mCameraDialog; private Uri mUri; //相机回调参数, public static final int REQ_CAMERA = 0x01; //系统图库参数 public static final int REQ_ALBUM = 0x02; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); initCameraDialog(); } public void initCameraDialog(){ mCameraDialog = new CameraAlbumDialog(this); mCameraDialog.getWindow().setGravity(Gravity.BOTTOM); // 拍照 mCameraDialog.setOnCameraClickListener(new View.OnClickListener() { @Override public void onClick(View v) { loadRealImgFromCamera(); mCameraDialog.dismiss(); } }); // 相册 mCameraDialog.setOnAlbumClickListener(new View.OnClickListener() { @Override public void onClick(View v) { loadImgFromAlbum(); mCameraDialog.dismiss(); } }); // 取消 mCameraDialog.setOnCancleClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mCameraDialog.dismiss(); } }); } /** * 跳转到另一个页面进行多图操作 */ private void loadImgFromAlbum() { Intent openAlbumIntent = new Intent(this, OpenAlbumActivity.class); startActivityForResult(openAlbumIntent,REQ_ALBUM); } /** * 打开照相机 */ private void loadRealImgFromCamera() { Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (mUri == null) { mUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "cameraImghead.jpg")); } cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mUri); startActivityForResult(cameraIntent, REQ_CAMERA); } /** * 相机回调和多图回调 */ public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQ_CAMERA && resultCode == -1) { jiantu(mUri); } else if (requestCode == 3 && resultCode == -1) { if (mUri != null&&listener!=null) { listener.getImgUrl(mUri); } }else if (requestCode == REQ_ALBUM&&resultCode == -1){ if (listener!=null){ listener.getImgUrl(data.getStringArrayListExtra("urls")); } } } /** * 拍照剪裁 */ private void jiantu(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); intent.putExtra("crop", "true"); intent.putExtra("scale", true); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); intent.putExtra("return-data", false); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true); // no face detection startActivityForResult(intent, 3); } public interface imgUrlListener{ void getImgUrl(Uri url); //返回一张图片的地址 void getImgUrl(ArrayList<String> urls); //返回一组图片的地址 } imgUrlListener listener; public void setListener(imgUrlListener listener) { this.listener = listener; } @Override protected void onDestroy() { super.onDestroy(); mCameraDialog = null; }在MainActivity里面进行进行监听图片选择后的监听回调,并在GridView里面进行显示代码如下,要注意权限,Android6.0应该在代码了主动调用获取相机授权。
mGridView = (GridView)findViewById(R.id.grid_photo); mData = new ArrayList<>(); mAdapter = new GridPhotoAdapter(this,mData); mGridView.setAdapter(mAdapter); /** * 监听项目需求最多选择6张图,不到6张就显示加号,选到6张就隐藏掉加号 */ setListener(new imgUrlListener() { @Override public void getImgUrl(Uri url) { mData.add(url.toString()); mAdapter.notifyDataSetChanged(); } @Override public void getImgUrl(ArrayList<String> urls) { for (int i = 0; i < urls.size(); i++) { if (mData.size() < 6) { mData.add(urls.get(i)); } } mAdapter.notifyDataSetChanged(); } }); /** * 当点击的位置等于图片数组的长度时,可以知道此时图片数小于6张,并且点击的是加号,显示选择图片的dialog */ mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { if (i == mData.size()) { mCameraDialog.show(); } } }); }因为需要显示加号而且需求是最多显示6张图片,所以要在adapter里面要进行逻辑上的操作private Context mContext; private List<String> mData; public GridPhotoAdapter(Context context, List<String> data){ mContext = context; mData = data; } @Override public int getCount() { if (mData.size()<6){ return mData.size()+1; }else{ return mData.size(); } } @Override public Object getItem(int i) { return mData.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { viewHolder holder; if (view == null){ view = LayoutInflater.from(mContext).inflate(R.layout.item_photo,null); holder = new viewHolder(); holder.simpleDraweeView = (ImageView) view.findViewById(R.id.image); holder.ivAdd = (ImageView) view.findViewById(R.id.iv_add); RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams((int) ScreenUtils.getScreenWidth(mContext)/3-20,(int)ScreenUtils.getScreenWidth(mContext)/3-20); holder.simpleDraweeView.setLayoutParams(lp); view.setTag(holder); }else{ holder = (viewHolder) view.getTag(); } if (mData.size() <= 6){ if (i < mData.size()){ holder.ivAdd.setVisibility(View.GONE); if (mData.get(i).contains("file:///")){ ImageLoader.getInstance(3, ImageLoader.Type.LIFO).loadImage(mData.get(i).substring(7), holder.simpleDraweeView); }else{ ImageLoader.getInstance(3, ImageLoader.Type.LIFO).loadImage(mData.get(i), holder.simpleDraweeView); } }else{ holder.ivAdd.setVisibility(View.VISIBLE); ImageLoader.getInstance(3, ImageLoader.Type.LIFO).loadImage("", holder.simpleDraweeView); } } return view; } class viewHolder{ ImageView simpleDraweeView; ImageView ivAdd; } public void onDestory(){ mContext = null; mData = null; }要注意调用相机返回的url地址和调用多图选择返回的url地址不一样,相机回调产生的地址前部分含有“file///”所以判断当含有这个字符串时要进行截取。然后显示。为了防止oom,在ImageLoder里面将图片的宽高根据比例压缩后,再度压缩2倍
/** * 计算inSampleSize,用于压缩图片 * * @param options * @param reqWidth * @param reqHeight * @return */private int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight){// 源图片的宽度int width = options.outWidth;int height = options.outHeight;int inSampleSize = 1;if (width > reqWidth && height > reqHeight){// 计算出实际宽度和目标宽度的比率int widthRatio = Math.round((float) width / (float) reqWidth);int heightRatio = Math.round((float) width / (float) reqWidth);inSampleSize = Math.max(widthRatio*2, heightRatio*2);}return inSampleSize;}源码已上传地址在http://download.csdn.net/detail/u013692888/9758445
0 0
- android多图选择器demo
- Android城市时间选择器Demo
- android多图选择器
- android Spinner和数值选择器使用demo
- 我的第一个android kotlin小demo 文件选择器
- Android简单的多图选择器
- JQuery选择器DEMO
- 【Android】时间选择器,选择日期DatePicker 简单详解demo及教程
- android选择器
- Android选择器
- android选择器
- [Android]时间选择器/日历选择器/选择器dialog
- android demo
- android demo
- android demo
- Android Demo
- CSS选择器汇总以及调试DEMO
- 一个iOS图片选择器的DEMO
- BAT工程师成长的几个阶段
- Objective-C简单的音乐播放器(边下边播)
- 什么是哈弗曼树
- PAT甲级练习1025. PAT Ranking (25)
- java大数据框架
- android多图选择器demo
- linux下特殊权限位的使用
- 14. Longest Common Prefix
- 解决Mac用Navicat连接Oracle数据库报ORA-21561: OID generation failed
- atexit FILE 粘滞位和缓冲区
- 被Nginx代理后从REQUEST获取客户端IP地址
- JSONP与跨域的Ajax
- Jackson
- [高性能MySQL]--MySQL的架构与概念