码迷,mamicode.com
首页 > 移动开发 > 详细

安卓开发 第八篇 我的安卓应用架构设计-----图片选择以及剪裁

时间:2016-05-18 18:24:10      阅读:321      评论:0      收藏:0      [点我收藏+]

标签:

Android开发中遇到要从相册选择图片时,大多数人都会选择调用Android自带的相册,毕竟这样可以节约时间,又不用自己去处理图片的问题,不过这样也会产生一些问题,有些系统自带的相册真的是丑到没朋友,有时调用系统相册时不时的还可能发生崩溃问题。而我的安卓架构中选择了自定义相册的功能,其效果是仿照QQ的图片选择样式,通过dialog展现出来的,还自定义了图片的剪裁,使用了CropImageView 实现了多种剪裁效果。

图片选择的直接辅助类:

/**
 * 图片选择辅助类
 * Created by tianlai on 16-4-12.
 */
public class PickImageHelper {
    private static final String TAG = "PickImageHelper";

    private PickType pickType;
    private Type type;

    private Activity activtiy;

    private PicKImageDialog picKImageDialog;
    private CropImageDialog cropImageDialog;

    private String cachePath;

    private OnImageOutputListener onImageOutputListener;

    @Inject
    public PickImageHelper(PicKImageDialog picKImageDialog) {
        this.picKImageDialog = picKImageDialog;
    }


    /**
     * 初始化
     *
     * @param activtiy
     */
    public void initPickImageHelper(final Activity activtiy) {
        this.activtiy = activtiy;

        picKImageDialog.setCancelable(false);

        cachePath = SDCardUtil.getRootPath() + activtiy.getString(R.string.cache_path);


        picKImageDialog.setPickImageListener(new PicKImageDialog.PickImageListener() {
            @Override
            public void onPickFinish(List<String> paths) {

                LogUtil.i(TAG, "已选的图片---" + paths.toString());

                picKImageDialog.dismiss();

                if (onImageOutputListener != null) {
                    if (pickType == PickType.HEADICON) {
                        onImageOutputListener.outputHeadImage(paths.get(0));
                    } else if (pickType == PickType.MULTIIMAGE) {
                        onImageOutputListener.outputPickedImages(paths);
                    }

                }
            }

            @Override
            public void toCropImage(String path) {
                LogUtil.i(TAG, "要剪裁的图片---" + path.toString());

                picKImageDialog.dismiss();
                initCropImageDialog(Uri.parse("file://" + path));

            }
        });


    }

    /**
     * 初始化剪裁的对话框
     *
     * @param path
     * @param activtiy
     */
    public void onCaptureResult(final String path, Activity activtiy) {
        this.activtiy = activtiy;

        new AlertDialog.Builder(activtiy)
                .setTitle("提示")
                .setMessage("是否剪裁图片?")
                .setNegativeButton("否", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dealCropResult(path);
                    }
                }).setPositiveButton("是", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                initCropImageDialog(Uri.parse("file://" + path));
            }
        }).create().show();

    }

    /**
     * 初始化剪裁的对话框
     *
     * @param uri
     */
    private void initCropImageDialog(Uri uri) {
        cropImageDialog = new CropImageDialog(activtiy);
        cropImageDialog.setCancelable(false);
        cropImageDialog.setCachePath(cachePath);

        cropImageDialog.setCropImageListener(new CropImageDialog.CropImageListener() {
            @Override
            public void onPickImage() {
                LogUtil.i(TAG, "---重新选择图片---");

                cropImageDialog.dismiss();
                picKImageDialog.setMaxNum(1);
                picKImageDialog.show();
            }

            @Override
            public void onCropSucceed(String path) {
                LogUtil.i(TAG, "剪裁后的图片路径---" + path);

                cropImageDialog.dismiss();
                dealCropResult(path);
            }
        });

        cropImageDialog.show(uri, true);
    }

    /**
     * 剪裁结果的处理
     *
     * @param path
     */
    private void dealCropResult(String path) {
        if (onImageOutputListener != null) {
            if (pickType == PickType.HEADICON) {
                onImageOutputListener.outputHeadImage(path);
            } else if (pickType == PickType.MULTIIMAGE) {
                List<String> paths = new ArrayList<String>();
                paths.add(path);
                onImageOutputListener.outputPickedImages(paths);
            }
        }
    }


    /**
     * 选择头像
     */
    public void pickHeadImage() {
        this.pickType = PickType.HEADICON;

        picKImageDialog.setMaxNum(1);

        showPickOrCapture();
    }

    /**
     * 选择图片
     */
    public void pickImages(int maxNum) {
        this.pickType = PickType.MULTIIMAGE;

        picKImageDialog.setMaxNum(maxNum);

        showPickOrCapture();

    }


    /**
     * 从相册选择或者拍照
     */
    private void showPickOrCapture() {
        new AlertDialog.Builder(activtiy)
                .setItems(R.array.pick_image, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        switch (which) {
                            case 0:      //拍照
                                type = Type.CAPTURE;
                                if (onImageOutputListener != null) {
                                    onImageOutputListener.takePhoto();
                                }

                                break;
                            case 1:      //图库
                                type = Type.PICKIMAGE;

                                picKImageDialog.show();

                                break;
                            case 2:      //取消
                                break;
                        }
                    }
                }).create().show();
    }


    public OnImageOutputListener getOnImageOutputListener() {
        return onImageOutputListener;
    }

    public void setOnImageOutputListener(OnImageOutputListener onImageOutputListener) {
        this.onImageOutputListener = onImageOutputListener;
    }

    public PickType getPickType() {
        return pickType;
    }

    public void setPickType(PickType pickType) {
        this.pickType = pickType;
    }

    //选择类型,单张头像还是多张
    public enum PickType {
        HEADICON, MULTIIMAGE
    }

    //选择类型,拍照还是图库
    public enum Type {
        CAPTURE, PICKIMAGE
    }

    public static interface OnImageOutputListener {

        public void takePhoto();

        /**
         * 输出头像
         *
         * @param path
         */
        public void outputHeadImage(String path);

        /**
         * 输出选择的图片
         *
         * @param paths
         */
        public void outputPickedImages(List<String> paths);
    }

}

图片选择dialog:

/**
 * 图片选择弹出对话框
 * <p/>
 * Created by tianlai on 16-4-12.
 */
public class PicKImageDialog extends Dialog {
    private Context context;

    private LayoutInflater inflater;

    private ImageView topHome;

    private TextView topTitle;

    private TextView topCenter;

    private TextView topAction;

    private GridView gvPictures;

    private ViewPager vpPictures;

    private ViewSwitcher vsPictures;

    private TextView bottomPreview;

    private TextView bottomCrop;

    private TextView bottomSure;

    private ListView lvPaths;

    private ViewSwitcher vsLayout;

    private List<ImageCollection> imagePaths;

    private Set<String> parentPaths;

    private ParentPathsAdapter parentPathsAdapter;

    private PicturesAdapter picturesAdapter;

    private PicturesPagerAdapter picturesPagerAdapter;

    private int maxNum;

    private PickImageListener pickImageListener;


    public PicKImageDialog(Context context) {
        super(context, R.style.AppTheme_Dialog);

        init(context);

    }

    public PicKImageDialog(Context context, int theme) {
        super(context, theme);


        init(context);
    }

    private void init(Context context) {
        this.context = context;

        inflater = LayoutInflater.from(context);

        imagePaths = new ArrayList<>();
        parentPaths = new HashSet<>();

        picturesAdapter = new PicturesAdapter(context, inflater);
        parentPathsAdapter = new ParentPathsAdapter(context, inflater);

        scanPictures(context);
    }

    /**
     * 扫描手机中的图片
     *
     * @param context
     */
    private void scanPictures(final Context context) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                ContentResolver mContentResolver = context.getContentResolver();
                String[] projections = {
                        MediaStore.Images.Media.DISPLAY_NAME,
                        MediaStore.Images.Media._ID,
                        MediaStore.Images.Media.DATA,
                        MediaStore.Images.Media.SIZE
                };
                String selection = MediaStore.Images.Media.MIME_TYPE + "=?";
                String[] selectionArgs = {"image/jpeg"};
                String sortOrder = MediaStore.Images.Media.DATE_MODIFIED + " desc";

                // 只查询jpeg和png的图片
                Cursor mCursor = mContentResolver.query(mImageUri, projections,
                        selection,
                        selectionArgs, sortOrder);
                if (mCursor != null) {
                    ImageCollection imageCollection;
                    while (mCursor.moveToNext()) {
                        imageCollection = new ImageCollection();
                        // 获取图片的uri路径
                        String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA));
                        if (path != null) {
                            File file = new File(path);
                            if (file != null && file.exists()) {

                                // 获取该图片的父路径名
                                File parentFile = file.getParentFile();
                                String parentPath = parentFile.getAbsolutePath();
                                if (parentPaths.contains(parentPath)) {
                                    continue;
                                } else {
                                    parentPaths.add(parentPath);
                                    imageCollection.setRootPath(parentPath);
                                    imageCollection.setRootName(parentFile.getName());

                                    File[] files = parentFile.listFiles();
                                    for (File f : files) {
                                        String fName = f.getName();
                                        if (fName.endsWith(".jpg") || fName.endsWith(".png")) {
                                            imageCollection.addPicture(f.getAbsolutePath());
                                        }
                                    }

                                    imagePaths.add(imageCollection);

                                }

                            }
                        }
                    }
                    mCursor.close();

                }
            }
        }).start();
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        setContentView(R.layout.dialog_pickimage);

        initView();

    }

    /**
     * 初始化view
     */
    private void initView() {
        topHome = (ImageView) find(R.id.top_home);
        topTitle = (TextView) find(R.id.top_title);
        topCenter = (TextView) find(R.id.top_center);
        topAction = (TextView) find(R.id.top_action);
        gvPictures = (GridView) find(R.id.gv_pictures);
        vpPictures = (ViewPager) find(R.id.vp_pictures);
        vsPictures = (ViewSwitcher) find(R.id.vs_pictures);
        bottomPreview = (TextView) find(R.id.bottom_title);
        bottomCrop = (TextView) find(R.id.bottom_center);
        bottomSure = (TextView) find(R.id.bottom_action);
        lvPaths = (ListView) find(R.id.lv_paths);
        vsLayout = (ViewSwitcher) find(R.id.vs_layout);


        setListeners();

        gvPictures.setAdapter(picturesAdapter);
        lvPaths.setAdapter(parentPathsAdapter);

        parentPathsAdapter.setItems(imagePaths);
        List<String> items = transToFullPath(imagePaths);
        parentPathsAdapter.addItem(0, new ImageCollection(new HashSet<String>(items), "所有图片"));
        picturesAdapter.setItems(items);
    }

    /**
     * 设置监听器
     */
    private void setListeners() {
        //返回
        topHome.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        //取消
        topAction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });
        //预览
        bottomPreview.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showPreviews(new ArrayList<String>(picturesAdapter.getSelectedPictures()));
            }
        });
        //剪裁
        bottomCrop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (pickImageListener != null) {
                    pickImageListener.toCropImage(picturesAdapter.getCorpPicturePath());
                    picturesAdapter.clearSelectedPictures();
                }
            }
        });
        //确定
        bottomSure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (pickImageListener != null) {
                    pickImageListener.onPickFinish(new ArrayList<String>(picturesAdapter.getSelectedPictures()));
                    picturesAdapter.clearSelectedPictures();
                }
            }
        });

        picturesAdapter.setOnPictrueSelectListener(new PicturesAdapter.OnPictrueSelectListener() {
            @Override
            public void selectedSingleItem(boolean selectedSingleItem) {
                if (selectedSingleItem) {
                    bottomCrop.setEnabled(true);
                } else {
                    bottomCrop.setEnabled(false);
                }
            }

            @Override
            public void hasItemSelected(boolean hasItemSelected, int selectNum) {
                if (hasItemSelected) {
                    bottomPreview.setEnabled(true);
                    bottomSure.setEnabled(true);
                    bottomSure.setText("确定(" + selectNum + "/" + maxNum + ")");
                } else {
                    bottomPreview.setEnabled(false);
                    bottomSure.setEnabled(false);
                    bottomSure.setText("确定");
                }
            }
        });

        //点击预览单张图片
        gvPictures.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                List<String> paths = new ArrayList<String>();
                String item = picturesAdapter.getItem(position);
                paths.add(item);

                showPreviews(paths);

                //判断是否可以剪裁
                if (bottomCrop.isEnabled() && !picturesAdapter.isSamePicture(item)) {
                    bottomCrop.setEnabled(false);
                }
            }
        });

        //点击查看某个目录下面的图片
        lvPaths.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                ImageCollection imageCollection = parentPathsAdapter.getItem(position);
                picturesAdapter.setItems(new ArrayList<String>(imageCollection.getPictures()));
                topCenter.setText(imageCollection.getRootName());
                vsLayout.showNext();

            }
        });

    }

    private void showPreviews(List<String> paths) {
        PicturesPagerAdapter adapter = new PicturesPagerAdapter(paths, inflater);
        vpPictures.setAdapter(adapter);

        vsPictures.showNext();

        //隐藏预览按钮
        bottomPreview.setVisibility(View.GONE);

    }

    /**
     * @param imagePaths
     * @return
     */
    private List<String> transToFullPath(List<ImageCollection> imagePaths) {

        Observable<String> observable = null;
        if (imagePaths != null) {
            int size = imagePaths.size();
            if (size > 0) {
                Observable<String> observableMerge;
                for (int i = 0; i < size; i++) {
                    Set<String> pictures = imagePaths.get(i).getPictures();
                    if (pictures == null) {
                        continue;
                    } else {
                        observableMerge = Observable.from(pictures);
                        if (observable == null) {
                            observable = observableMerge;
                        } else {
                            observable = Observable.merge(observable, observableMerge);
                        }
                    }

                }

                return observable.distinct().toList().toBlocking().single();


            }
        }

        return Collections.emptyList();
    }

    /**
     * 初始化dialog
     *
     * @param maxNum
     * @param pickImageListener
     */
    public void initPickDialog(int maxNum, PickImageListener pickImageListener) {
        this.maxNum = maxNum;
        this.pickImageListener = pickImageListener;

    }

    @Override
    public void show() {
        picturesAdapter.setMaxNum(maxNum);
        super.show();

        setDialogWindowAttr();
    }

    /**
     * 调整dialog的大小
     */
    public void setDialogWindowAttr() {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.gravity = Gravity.CENTER;
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;//宽高可设置具体大小
        lp.height = WindowManager.LayoutParams.MATCH_PARENT;
        getWindow().setAttributes(lp);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (lvPaths.isShown()) {
            dismiss();
        } else if (vpPictures.isShown()) {
            vsPictures.showNext();

            //显示预览按钮
            bottomPreview.setVisibility(View.VISIBLE);

            //判断是否可以剪裁
            if (!bottomCrop.isEnabled() && picturesAdapter.isSelectedSingleItem()) {
                bottomCrop.setEnabled(true);
            }
        } else {
            vsLayout.showNext();
        }
    }

    public int getMaxNum() {
        return maxNum;
    }

    public void setMaxNum(int maxNum) {
        this.maxNum = maxNum;
    }

    public PickImageListener getPickImageListener() {
        return pickImageListener;
    }

    public void setPickImageListener(PickImageListener pickImageListener) {
        this.pickImageListener = pickImageListener;
    }

    /**
     * 获取view
     *
     * @param viewId
     * @return
     */
    public View find(int viewId) {
        return findViewById(viewId);
    }

    /**
     * 获取view
     *
     * @param viewId
     * @return
     */
    public View find(View parent, int viewId) {
        return parent.findViewById(viewId);
    }

    public static interface PickImageListener {
        /**
         * 选择图片完成
         */
        public void onPickFinish(List<String> paths);

        /**
         * 剪裁图片
         */
        public void toCropImage(String path);
    }

}

图片的封装对象:

/**
 * 封装一个目录及其目录下的图片文件的路径
 * Created by tianlai on 16-4-12.
 */
public class ImageCollection {
    private String rootPath;
    private String rootName;
    private Set<String> pictures;

    public ImageCollection() {
    }

    public ImageCollection(Set<String> pictures, String rootName) {
        this.pictures = pictures;
        this.rootName = rootName;
    }

    public String getRootPath() {
        return rootPath;
    }

    public void setRootPath(String rootPath) {
        this.rootPath = rootPath;
    }

    public Set<String> getPictures() {
        return pictures;
    }

    public void setPictures(Set<String> pictures) {
        this.pictures = pictures;
    }

    public void addPicture(String picture){
        if (pictures==null){
            pictures=new HashSet<>();
        }

        pictures.add(picture);
    }

    public void rmPicture(String picture){
        if (pictures==null){
            return;
        }

        pictures.remove(picture);
    }

    public String getRootName() {
        return rootName;
    }

    public void setRootName(String rootName) {
        this.rootName = rootName;
    }

    @Override
    public String toString() {
        return "ImageCollection{" +
                "rootPath=‘" + rootPath + ‘\‘‘ +
                ", pictures=" + pictures +
                ‘}‘;
    }
}

图片显示适配器:

/**
 * 图片显示页面的适配器
 * Created by tianlai on 16-4-12.
 */
public class PicturesAdapter extends BaseAbsListAdapter<String,PicturesViewHolder> {
    private Set<String> selectedPictures;

    private OnPictrueSelectListener  onPictrueSelectListener;

    private int maxNum;

    public PicturesAdapter(Context context, LayoutInflater inflater) {

        super(context, inflater);

        selectedPictures=new HashSet<>();
    }

    @Override
    public PicturesViewHolder onCreateViewHolder(ViewGroup parent, int viewType, LayoutInflater inflater) {
        return new PicturesViewHolder(inflater.inflate(R.layout.grid_item_select_image,null),this);
    }


    public Set<String> getSelectedPictures() {
        return selectedPictures;
    }

    public void setSelectedPictures(Set<String> selectedPictures) {
        this.selectedPictures = selectedPictures;
    }

    public void addSelectedPicture(String path){
        selectedPictures.add(path);

        notifySelectedItem();
    }

    public void removeSelectedPicture(String path){
        selectedPictures.remove(path);

        notifySelectedItem();
    }

    /**
     * 有item选中或者取消选中时的事件
     */
    private void notifySelectedItem() {
        if (onPictrueSelectListener!=null){
            int size = selectedPictures.size();
            onPictrueSelectListener.selectedSingleItem(size==1);
            onPictrueSelectListener.hasItemSelected(size >0,size);
        }
    }

    public boolean isSlected(String path){
        Log.i("picture",selectedPictures.toString());
        return selectedPictures.contains(path);
    }

    public OnPictrueSelectListener getOnPictrueSelectListener() {
        return onPictrueSelectListener;
    }

    public void setOnPictrueSelectListener(OnPictrueSelectListener onPictrueSelectListener) {
        this.onPictrueSelectListener = onPictrueSelectListener;
    }

    public int getMaxNum() {
        return maxNum;
    }

    public void setMaxNum(int maxNum) {
        this.maxNum = maxNum;
    }

    public boolean isCanSelectMore(){
        return selectedPictures.size()<maxNum;
    }

    public boolean isSelectedSingleItem(){
        return selectedPictures.size()==1;
    }

    public boolean isSamePicture(String path){
        if (isSelectedSingleItem()){
            if (new ArrayList<String>(selectedPictures).get(0).equals(path)){
                return true;
            }
        }

        return  false;
    }

    /**
     * 获取要剪裁的图片路径
     *
     * @return
     */
    public String getCorpPicturePath(){
        if (selectedPictures.size()==1){
            return new ArrayList<>(selectedPictures).get(0);
        }

        return null;
    }

    /**
     * 清空选中的图片
     */
    public void clearSelectedPictures(){
        selectedPictures.clear();
    }

    public static interface OnPictrueSelectListener{
        public void selectedSingleItem(boolean selectedSingleItem);

        public void hasItemSelected(boolean hasItemSelected, int selectNum);
    }
}

图片显示的Viewholder:

/**
 * 图片显示页面的适配器的ViewHolder
 * Created by tianlai on 16-4-12.
 */
public class PicturesViewHolder extends BaseViewHolder<String> implements  CompoundButton
        .OnCheckedChangeListener {

    SimpleDraweeView sdvPicture;

    CheckBox cbSelect;

    private ImageRequest imageRequest;
    private DraweeController draweeController;

    public PicturesViewHolder(View convertView, BaseAbsListAdapter absListAdapter) {
        super(convertView, absListAdapter);

        sdvPicture = (SimpleDraweeView) find(R.id.sdv_picture);
        cbSelect = (CheckBox) find(R.id.cb_select);

        cbSelect.setOnCheckedChangeListener(this);
    }

    @Override
    public void loadDataToView(int position, String data) {
        super.loadDataToView(position,data);

        imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse("file://" + data))
                .setResizeOptions(new ResizeOptions(128,128))
                .setLocalThumbnailPreviewsEnabled(true)
                .build();
        draweeController = Fresco.newDraweeControllerBuilder()
                .setImageRequest(imageRequest)
                .setOldController(sdvPicture.getController())
                .build();

        sdvPicture.setController(draweeController);

        if (((PicturesAdapter) absListAdapter).isSlected(data)) {
            cbSelect.setChecked(true);
            Log.i("picture","位置"+position+"--已选中");
        }else {
            cbSelect.setChecked(false);
            Log.i("picture","位置"+position+"--未选中");
        }

    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                if (((PicturesAdapter) absListAdapter).isCanSelectMore()||((PicturesAdapter) absListAdapter).isSlected(data)){
                    ((PicturesAdapter) absListAdapter).addSelectedPicture(data);
                    Log.i("picture","位置"+position+"--正在点击选中");
                }else {
                    Toast.makeText(context,"最多只能选择"+((PicturesAdapter) absListAdapter).getMaxNum()+"张图片",Toast
                            .LENGTH_SHORT).show();
                    buttonView.setChecked(false);
                }
            } else {
                ((PicturesAdapter) absListAdapter).removeSelectedPicture(data);
                Log.i("picture","位置"+position+"--正在取消选中");
            }
    }

}

图片文件夹页面适配器:

/**
 * 选择图片文件夹页面的适配器 
 * Created by tianlai on 16-4-12.
 */
public class ParentPathsAdapter extends BaseAbsListAdapter<ImageCollection,ParentPathsViewHolder> {

    public ParentPathsAdapter(Context context, LayoutInflater inflater) {
        super(context, inflater);
    }

    @Override
    public ParentPathsViewHolder onCreateViewHolder(ViewGroup parent, int viewType, LayoutInflater inflater) {
        return new ParentPathsViewHolder(inflater.inflate(R.layout.list_item_parent_paths,null),this);
    }
}

图片文件夹页面ViewHolder:

/**
 * 选择图片文件夹页面的适配器的ViewHolder
 * Created by tianlai on 16-4-12.
 */
public class ParentPathsViewHolder extends BaseViewHolder<ImageCollection> {

    SimpleDraweeView sdvImage;

    TextView tvPath;

    public ParentPathsViewHolder(View convertView, BaseAbsListAdapter absListAdapter) {
        super(convertView, absListAdapter);

        sdvImage= (SimpleDraweeView) find(R.id.sdv_image);
        tvPath= (TextView) find(R.id.tv_path);
    }

    @Override
    public void loadDataToView(int position, ImageCollection data) {
        List<String> pictures = new ArrayList<>(data.getPictures());
        if (pictures != null) {
            int size = pictures.size();
            if (size > 0) {
                sdvImage.setImageURI(Uri.parse("file://" + pictures.get(0)));
                tvPath.setText(data.getRootName() + "(" + size + ")");
            }
        }
    }

}

选中的图片预览适配器:

/**
 * 浏览选中的图片的适配器(浏览页面是一个ViewPager)
 * Created by tianlai on 16-4-12.
 */
public class PicturesPagerAdapter extends PagerAdapter {
    private List<View> images;

    private List<String> picturePaths;

    private LayoutInflater inflater;

    public PicturesPagerAdapter(List<String> picturePaths, LayoutInflater inflater) {
        this.inflater = inflater;
        this.picturePaths=picturePaths;

        images = new ArrayList<View>();

        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup
                .LayoutParams.MATCH_PARENT);

        View view;

        for (String path : picturePaths) {
            view=inflater.inflate(R.layout.vp_item_picture,null);
            ((SimpleDraweeView)view.findViewById(R.id.vp_picture)).setImageURI(Uri.parse("file://"+path));
            images.add(view);
        }


    }

    @Override
    public int getCount() {
        return images.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }


    @Override
    public Object instantiateItem(ViewGroup container, int position) {

        View view = images.get(position);
        container.addView(view);

        return view;
    }

    public List<String> getPicturePaths() {
        return picturePaths;
    }

    public void setPicturePaths(List<String> picturePaths) {
        this.picturePaths = picturePaths;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(images.get(position));
    }


}

剪裁图片dialog:

/**
 * 剪裁图片的对话框
 * Created by tianlai on 16-4-13.
 */
public class CropImageDialog extends Dialog {

    private Context context;

    private LayoutInflater inflater;

    // Views ///////////////////////////////////////////////////////////////////////////////////////
    private CropImageView mCropView;
    private LinearLayout mRootLayout;
    private ProgressBar progressBar;

    private String cachePath;
    private String cropPath;

    private boolean isFromPick;

    private CropImageListener cropImageListener;

    public CropImageDialog(Context context) {
        super(context, R.style.AppTheme_Dialog);

        init(context);

    }

    public CropImageDialog(Context context, int theme) {
        super(context, theme);


        init(context);
    }

    private void init(Context context) {
        this.context = context;
        inflater = LayoutInflater.from(context);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        View contentView = inflater.inflate(R.layout.dialog_cropimage, null);

        setContentView(contentView);

        // bind Views
        bindViews(contentView);

        mCropView.setDebug(BuildConfig.DEBUG);
    }


    private void bindViews(View view) {
        progressBar = (ProgressBar) view.findViewById(R.id.progress);
        progressBar.getIndeterminateDrawable().setColorFilter(getContext().getResources().getColor(R.color.colorAccent),
                PorterDuff.Mode.SRC_IN);
        mRootLayout = (LinearLayout) view.findViewById(R.id.layout_root);

        mCropView = (CropImageView) view.findViewById(R.id.cropImageView);
        mCropView.setOutputMaxSize(300, 300);

        view.findViewById(R.id.top_home).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });

        view.findViewById(R.id.top_action).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });

        view.findViewById(R.id.buttonDone).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showProgress();
                mCropView.startCrop(createSaveUri(), mCropCallback, mSaveCallback);
            }
        });
        view.findViewById(R.id.buttonFitImage).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.setCropMode(CropImageView.CropMode.FIT_IMAGE);
            }
        });
        view.findViewById(R.id.button1_1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.setCropMode(CropImageView.CropMode.SQUARE);
            }
        });
        view.findViewById(R.id.button3_4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.setCropMode(CropImageView.CropMode.RATIO_3_4);
            }
        });
        view.findViewById(R.id.button4_3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.setCropMode(CropImageView.CropMode.RATIO_4_3);
            }
        });
        view.findViewById(R.id.button9_16).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.setCropMode(CropImageView.CropMode.RATIO_9_16);
            }
        });
        view.findViewById(R.id.button16_9).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.setCropMode(CropImageView.CropMode.RATIO_16_9);
            }
        });
        view.findViewById(R.id.buttonFree).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.setCropMode(CropImageView.CropMode.FREE);
            }
        });
        view.findViewById(R.id.buttonPickImage).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (cropImageListener != null) {
                    cropImageListener.onPickImage();
                }
            }
        });
        view.findViewById(R.id.buttonRotateLeft).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.rotateImage(CropImageView.RotateDegrees.ROTATE_M90D);
            }
        });
        view.findViewById(R.id.buttonRotateRight).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.rotateImage(CropImageView.RotateDegrees.ROTATE_90D);
            }
        });
        view.findViewById(R.id.buttonCustom).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.setCustomRatio(7, 5);
            }
        });
        view.findViewById(R.id.buttonCircle).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.setCropMode(CropImageView.CropMode.CIRCLE);
            }
        });
        view.findViewById(R.id.buttonShowCircleButCropAsSquare).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCropView.setCropMode(CropImageView.CropMode.CIRCLE_SQUARE);
            }
        });

    }

    /**
     * 创建保存剪裁图片的Uri
     *
     * @return
     */
    public Uri createSaveUri() {
        try {
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                //检查路径是否存在
                File dir = new File(cachePath);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                //检查文件是否存在
                File file = new File(cachePath, "cropped.jpg");
                if (!file.exists()) {
                    file.createNewFile();
                }

                cropPath = file.getAbsolutePath();

                return Uri.fromFile(file);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();

        if (isFromPick) {
            if (cropImageListener != null) {
                cropImageListener.onPickImage();

                return;
            }
        }

        dismiss();

    }

    private void showProgress() {
        progressBar.setVisibility(View.VISIBLE);
    }

    private void dismissProgress() {
        progressBar.setVisibility(View.GONE);
    }

    /**
     * @param cachePath
     * @param pickImageListener
     */
    public void initCropDialog(String cachePath, CropImageListener pickImageListener) {
        this.cropImageListener = pickImageListener;
        this.cachePath = cachePath;
    }

    /**
     * 开始剪裁
     *
     * @param pictureUri 要剪裁的图片的Uri
     */
    public void show(Uri pictureUri, boolean isFromPick) {

        Log.i("CropImageDialog", pictureUri.toString());

        this.isFromPick = isFromPick;

        super.show();
        setDialogWindowAttr();

        showProgress();
        mCropView.startLoad(pictureUri, mLoadCallback);

    }
//    /**
//     * 开始剪裁
//     *
//     * @param pictureUri
//     * @param isFromPick
//     */
//    public void show(Uri pictureUri, boolean isFromPick) {
//        super.show();
//
//        setDialogWindowAttr();
//
//        Log.i("CropImageDialog", pictureUri.toString());
//
//        this.isFromPick = isFromPick;
//
//        showProgress();
//        mCropView.setImageURI(pictureUri);
//
//    }

    /**
     * 调整dialog的大小
     */
    public void setDialogWindowAttr() {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.gravity = Gravity.CENTER;
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;//宽高可设置具体大小
        lp.height = WindowManager.LayoutParams.MATCH_PARENT;
        getWindow().setAttributes(lp);
    }

    public String getCachePath() {
        return cachePath;
    }

    public void setCachePath(String cachePath) {
        this.cachePath = cachePath;
    }

    public CropImageListener getCropImageListener() {
        return cropImageListener;
    }

    public void setCropImageListener(CropImageListener cropImageListener) {
        this.cropImageListener = cropImageListener;
    }

    // Callbacks ///////////////////////////////////////////////////////////////////////////////////

    private final LoadCallback mLoadCallback = new LoadCallback() {
        @Override
        public void onSuccess() {
            dismissProgress();
        }

        @Override
        public void onError() {
            dismissProgress();
        }
    };


    private final CropCallback mCropCallback = new CropCallback() {
        @Override
        public void onSuccess(Bitmap cropped) {
        }

        @Override
        public void onError() {
        }
    };

    private final SaveCallback mSaveCallback = new SaveCallback() {
        @Override
        public void onSuccess(Uri outputUri) {
            dismissProgress();

            if (cropImageListener != null) {
                cropImageListener.onCropSucceed(cropPath);
            }
        }

        @Override
        public void onError() {
            dismissProgress();
        }
    };

    public static interface CropImageListener {
        /**
         * 选择图片
         */
        public void onPickImage();

        /**
         * 剪裁成功
         *
         * @param path
         */
        public void onCropSucceed(String path);
    }
}

下面来看看效果图:

1.图片显示页面

技术分享

2.图片文件夹显示页面

技术分享

3.选中的图片的预览页面

技术分享

4.图片剪裁页面

技术分享

好了,就到这里吧!

如果有更深的理解,本文将会修改;
如果有错误的地方,欢迎指正;
如果你有更好的理解,欢迎交流。

本文为原创文章,版权归博主所有,转载请注明出处。

更多资料:

我的github地址以及使用demo: https://github.com/naivor/naivorapp

安卓开发 第八篇 我的安卓应用架构设计-----图片选择以及剪裁

标签:

原文地址:http://blog.csdn.net/naivor/article/details/51439618

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!