频道栏目
首页 > 资讯 > 微信公众平台开发 > 正文

android 仿微信多图选择器(带预览、照相功能)

16-07-28        来源:[db:作者]  
收藏   我要投稿
  • 实现了单选、多选 、拍照 、预览 等功能;先上图:

    代码结构

    下面不如正题:

    一、添加依赖、权限

    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

    
    
    二、主要代码

     

    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 mLoaderCallback = new LoaderManager.LoaderCallbacks() {
    
        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 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 loader, Cursor data) {
            if (data != null) {
                if (data.getCount() > 0) {
                    List 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 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 imagesMode = images;
                    mImageAdapter.setOnItemClickListerner(new OnItemClickListerner() {
                        @Override
                        public void onPhotoClick(View view, int position) {
                            List 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 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 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 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焦点获取不到,然后就没有然后了。。p>

相关TAG标签
上一篇:Linux 进程管理与监控(supervisor and monit)
下一篇:注重技术超过内容,BuzzFeed是最叛逆的媒体平台吗?"
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站