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