您的位置:首页 > 运维架构 > 网站架构

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

2016-05-17 21:30 846 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: