概述
- 实现了单选、多选 、拍照 、预览 等功能;
先上图:
代码结构
下面不如正题:
一、添加依赖、权限
1)添加以下依赖
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' compile 'com.squareup.picasso:picasso:2.4.0' compile 'com.nineoldandroids:library:2.4.0'
}
2) 在 AndroidManifest.xml 添加权限,并注册相关Activity
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>二、主要代码
1)设置参数
2)在图片选择的MultiImageSelectorFragment中添加接口,用于选择图片回调
public interface Callback { void onSingleImageSelected(String path); void onImageSelected(String path); void onImageUnselected(String path); void onCameraShot(File imageFile); }
3)扫描手机相册图片
private LoaderManager.LoaderCallbacks<Cursor> mLoaderCallback = new LoaderManager.LoaderCallbacks<Cursor>() { private final String[] IMAGE_PROJECTION = { MediaStore.Images.Media.DATA, MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.DATE_ADDED, MediaStore.Images.Media.MIME_TYPE, MediaStore.Images.Media.SIZE, MediaStore.Images.Media._ID}; @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { if (id == LOADER_ALL) { CursorLoader cursorLoader = new CursorLoader(getActivity(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION, IMAGE_PROJECTION[4] + ">0 AND " + IMAGE_PROJECTION[3] + "=? OR " + IMAGE_PROJECTION[3] + "=? ", new String[]{"image/jpeg", "image/png"}, IMAGE_PROJECTION[2] + " DESC"); return cursorLoader; } else if (id == LOADER_CATEGORY) { CursorLoader cursorLoader = new CursorLoader(getActivity(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION, IMAGE_PROJECTION[4] + ">0 AND " + IMAGE_PROJECTION[0] + " like '%" + args.getString("path") + "%'", null, IMAGE_PROJECTION[2] + " DESC"); return cursorLoader; } return null; } private boolean fileExist(String path) { if (!TextUtils.isEmpty(path)) { return new File(path).exists(); } return false; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { if (data != null) { if (data.getCount() > 0) { List<Image> images = new ArrayList<>(); data.moveToFirst(); do { String path = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[0])); String name = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[1])); long dateTime = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[2])); Image image = null; if (fileExist(path)) { image = new Image(path, name, dateTime); images.add(image); } if (!hasFolderGened) { // 获取文件夹名称 File folderFile = new File(path).getParentFile(); if (folderFile != null && folderFile.exists()) { String fp = folderFile.getAbsolutePath(); Folder f = getFolderByPath(fp); if (f == null) { Folder folder = new Folder(); folder.name = folderFile.getName(); folder.path = fp; folder.cover = image; List<Image> imageList = new ArrayList<>(); imageList.add(image); folder.images = imageList; mResultFolder.add(folder); } else { f.images.add(image); } } } } while (data.moveToNext()); mImageAdapter.setData(images); // 设定默认选择 if (resultList != null && resultList.size() > 0) { mImageAdapter.setDefaultSelected(resultList); } final List<Image> imagesMode = images; mImageAdapter.setOnItemClickListerner(new OnItemClickListerner() { @Override public void onPhotoClick(View view, int position) { List<String> mImgUrls = new ArrayList<>(); for (int i = 0; i < imagesMode.size(); i++) { mImgUrls.add(imagesMode.get(i).path); } int[] screenLocation = new int[2]; view.getLocationOnScreen(screenLocation); MultiImageSelectorPagerFragment fragment = MultiImageSelectorPagerFragment .newInstance(mImgUrls, position, mDesireImageCount, screenLocation, view.getWidth(), view.getHeight()); ((MultiImageSelectorActivity) getActivity()).addPhotoPagerFragment(fragment); } @Override public void onMarkClick(Image image, int mode) { selectImageFromGrid(image, mode); } }); if (!hasFolderGened) { if (mDirPopupWindow != null) { mDirPopupWindow.setDatas(mResultFolder); hasFolderGened = true; } } } } } @Override public void onLoaderReset(Loader<Cursor> loader) { } }; private Folder getFolderByPath(String path) { if (mResultFolder != null) { for (Folder folder : mResultFolder) { if (TextUtils.equals(folder.path, path)) { return folder; } } } return null; }
4)选择图片
private void selectImageFromGrid(Image image, int mode) { Log.e(TAG, "resultList = " + resultList.size()); if (image != null) { // 多选模式 if (mode == MODE_MULTI) { if (resultList.contains(image.path)) { resultList.remove(image.path); if (resultList.size() != 0) { mPreviewBtn.setEnabled(true); mPreviewBtn.setText(String.format("%s(%d)", getResources().getString(R.string.preview), resultList.size())); } else { mPreviewBtn.setEnabled(false); mPreviewBtn.setText(R.string.preview); } if (mCallback != null) { mCallback.onImageUnselected(image.path); } } else { // 判断选择数量问题 if (mDesireImageCount == resultList.size()) { Toast.makeText(getActivity(), R.string.msg_amount_limit, Toast.LENGTH_SHORT).show(); return; } resultList.add(image.path); mPreviewBtn.setEnabled(true); mPreviewBtn.setText(String.format("%s(%d)", getResources().getString(R.string.preview), resultList.size())); if (mCallback != null) { mCallback.onImageSelected(image.path); } } mImageAdapter.select(image); } else if (mode == MODE_SINGLE) { // 单选模式 if (mCallback != null) { mCallback.onSingleImageSelected(image.path); } } } }
5)展现文件夹的PopupWindow
private void initListDirPopupWindow() { //屏幕高度 int mScreenHeight = getScreenHeight(); Log.e(TAG, "mResultFolder = " + mResultFolder.size() + ", mScreenHeight = " + mScreenHeight); mDirPopupWindow = new ListImageDirPopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, (int) (0.7 * mScreenHeight), mResultFolder, LayoutInflater.from(getActivity()) .inflate(R.layout.list_folder, null)); mDirPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { //设置背景颜色变暗 WindowManager.LayoutParams lp = getActivity().getWindow().getAttributes(); lp.alpha = 1.0f; getActivity().getWindow().setAttributes(lp); } }); //设置选择文件夹的回调 mDirPopupWindow.setOnPhotoDirSelected(new ListImageDirPopupWindow.OnPhotoDirSelected() { @Override public void onSelected(List<Folder> datas, int position) { SharedPreferencesUtils.setParam(getActivity(), "FolderSelectIndex", position); if (position == 0) { getActivity().getSupportLoaderManager().restartLoader(LOADER_ALL, null, mLoaderCallback); mCategoryText.setText(R.string.folder_all); if (mIsShowCamera) { mImageAdapter.setShowCamera(true); } else { mImageAdapter.setShowCamera(false); } } else { final Folder folder = datas.get(position); if (null != folder) { mImageAdapter.setData(folder.images); mCategoryText.setText(folder.name); // 设定默认选择 if (resultList != null && resultList.size() > 0) { mImageAdapter.setDefaultSelected(resultList); } mImageAdapter.setOnItemClickListerner(new OnItemClickListerner() { @Override public void onPhotoClick(View view, int position) { List<String> mImgUrls = new ArrayList<>(); for (int i = 0; i < folder.images.size(); i++) { mImgUrls.add(folder.images.get(i).path); } int[] screenLocation = new int[2]; view.getLocationOnScreen(screenLocation); MultiImageSelectorPagerFragment fragment = MultiImageSelectorPagerFragment .newInstance(mImgUrls, position, mDesireImageCount, screenLocation, view.getWidth(), view.getHeight()); ((MultiImageSelectorActivity) getActivity()).addPhotoPagerFragment(fragment); } @Override public void onMarkClick(Image image, int mode) { selectImageFromGrid(image, mode); } }); } mImageAdapter.setShowCamera(false); } mGridView.smoothScrollToPosition(0); mDirPopupWindow.dismiss(); } }); }
好了,到此结束;整篇由于篇幅原因没有贴任何布局文件,大家自己通过源码查看;
在此希望大家可以通过该案例,能够去其糟粕,取其精华,学习其中值得借鉴的代码风格,不要真的当作一个例子去学习~~
备注:源码中还存在部分异常未处理:如
1)点击预览后,文件夹数量会翻倍,解决方案
2)切换文件夹目录gridview未滑动回顶部
虽然设置了mGridView.smoothScrollToPosition(0),但是也没有效果;网上查到的结果是gridview焦点获取不到,然后就没有然后了。。(本人未去证实),希望有解决方案的朋友留个言,谢谢!
...........................................................................
如有不足之处,望指正!谢谢!
源码地址
转载请注明:http://blog.csdn.net/qq_27305737/article/details/51983796
最后
以上就是朴实飞鸟为你收集整理的android 仿微信多图选择器(带预览、照相功能)的全部内容,希望文章能够帮你解决android 仿微信多图选择器(带预览、照相功能)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复