public class PictureCropActivity extends PictureBaseActivity implements CropImageView.OnBitmapSaveCompleteListener {

    public static final String EXTRA_NAME_CROP_IMG_PATH = "cropImgPath";

    private CropOptions cropOptions;

    private CropImageView cvCropImage;


    public static void startPictureCropActivity(Activity activity, String imgPath, CropOptions cropOptions, int requestCode) {
        Intent intent = new Intent(activity, PictureCropActivity.class);
        intent.putExtra("imgPath", imgPath);
        intent.putExtra("CropOptions", cropOptions);
        activity.startActivityForResult(intent, requestCode);
    }


    public static void startPictureCropActivity(android.app.Fragment fragment, String imgPath, CropOptions cropOptions, int requestCode) {
        Intent intent = new Intent(fragment.getActivity(), PictureCropActivity.class);
        intent.putExtra("imgPath", imgPath);
        intent.putExtra("CropOptions", cropOptions);
        fragment.startActivityForResult(intent, requestCode);
    }

    public static void startPictureCropActivity(android.support.v4.app.Fragment fragment, String imgPath, CropOptions cropOptions, int requestCode) {
        Intent intent = new Intent(fragment.getActivity(), PictureCropActivity.class);
        intent.putExtra("imgPath", imgPath);
        intent.putExtra("CropOptions", cropOptions);
        fragment.startActivityForResult(intent, requestCode);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_picture_crop);
        assignViews();
        titleBarHelper.getTitleTextView().setText(R.string.crop_picture);
        cropOptions = (CropOptions) getIntent().getSerializableExtra("CropOptions");

        cvCropImage.setFocusStyle(cropOptions.getStyle());
        cvCropImage.setFocusWidth(cropOptions.getFocusWidth());
        cvCropImage.setFocusHeight(cropOptions.getFocusHeight());

        final String imgPath = getIntent().getStringExtra("imgPath");

//        cvCropImage.setImageBitmap(createBitmap(imgPath));
        //用glide 可以不用关心图片压缩和角度颠倒问题，asBitmap 使gif只显示第一帧，
        Glide.with(PictureCropActivity.this).asBitmap().load(imgPath).into(cvCropImage);

        titleBarHelper.getCompleteButton().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                cvCropImage.saveBitmapToFile(new File(Utils.createTakePhotoFolderPath(getApplication())), cropOptions.getOutPutX(), cropOptions.getOutPutY(), cropOptions.isSaveRectangle());
            }
        });
        cvCropImage.setOnBitmapSaveCompleteListener(PictureCropActivity.this);

    }

    private void assignViews() {
        cvCropImage = (CropImageView) findViewById(R.id.cv_crop_image);
    }


    private Bitmap createBitmap(String imagePath) {
        //缩放图片
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePath, options);
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        options.inSampleSize = calculateInSampleSize(options, displayMetrics.widthPixels, displayMetrics.heightPixels);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(imagePath, options);
    }

    private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        int width = options.outWidth;
        int height = options.outHeight;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            if (width > height) {
                inSampleSize = width / reqWidth;
            } else {
                inSampleSize = height / reqHeight;
            }
        }
        return inSampleSize;
    }

    @Override
    public void onBitmapSaveSuccess(File file) {
        Intent intent = new Intent();
        intent.putExtra(EXTRA_NAME_CROP_IMG_PATH, file.getAbsolutePath());
        setResult(RESULT_OK, intent);
        finish();
    }

    @Override
    public void onBitmapSaveError(File file) {
        Utils.showToast(getApplicationContext(), getResources().getString(R.string.corp_picture_error));
    }


} public class PictureGridActivity extends PictureBaseActivity implements View.OnClickListener, PicturePicker.OnPictureSelectedListener {

    public static final int RECYCLER_VIEW_COLUMN = 4;

    /**
     * 打开相机请求码
     */
    private final int OPEN_CAMERA_REQUEST_CODE = 1001;

    /**
     * 去预览并选择图片请求码
     */
    private final int PREVIEW_IMAGE_REQUEST_CODE = 1002;


    public static final String EXTRA_RESULT_PICK_IMAGES = "extra_result_pick_pictures";

    private String takePhotoPath;

    private PictureScanner pictureScanner;
    private PicturePicker picturePicker = PicturePicker.getInstance();

    private RecyclerView rvPictures;
    private LinearLayout llFootBar;
    private TextView btnImgFolder;
    private Button btnImgPreview;

    private PictureGridAdapter pictureGridAdapter;
    private List<PictureItem> currentPictureItemList = new ArrayList<>();

    private PopupFolderListAdapter folderListAdapter;
    private List<PictureFolder> pictureFolderList = new ArrayList<>();

    private ListPopupWindow listPopupWindow;


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

        if (savedInstanceState != null) {
            takePhotoPath = savedInstanceState.getString("takePhotoPath");
            picturePicker.setPickPictureOptions((PickOptions) savedInstanceState.getSerializable("pickPictureOptions"));
        }

        if (picturePicker.getPickPictureOptions().isJustTakePhoto()) {
            openCamera();
            return;
        }

        setContentView(R.layout.activity_picture_grid);
        assignViews();
        setListener();
        initRvPictures();

        picturePicker.registerPictureSelectedListener(this);

        if (!picturePicker.getPickPictureOptions().isMultiMode()) {
            titleBarHelper.getCompleteButton().setVisibility(View.GONE);
            btnImgPreview.setVisibility(View.GONE);
        }

        refreshTitleBarCompleteBtnText(0);
        listPopupWindow = initFolderListPopupWindow();
        scanAllPictureFolder();
    }


    private void assignViews() {
        rvPictures = (RecyclerView) findViewById(R.id.rv_pictures);
        llFootBar = (LinearLayout) findViewById(R.id.ll_foot_bar);
        btnImgFolder = (TextView) findViewById(R.id.btn_img_folder);
        btnImgPreview = (Button) findViewById(R.id.btn_img_preview);
    }

    private void setListener() {
        btnImgFolder.setOnClickListener(this);
        btnImgPreview.setOnClickListener(this);

        titleBarHelper.getCompleteButton().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setResult();
            }
        });
    }


    private void initRvPictures() {

        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, RECYCLER_VIEW_COLUMN);
        rvPictures.setLayoutManager(gridLayoutManager);
        pictureGridAdapter = new PictureGridAdapter(this, currentPictureItemList);
        rvPictures.setAdapter(pictureGridAdapter);

        pictureGridAdapter.setOnItemClickListener(new PictureGridAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(ItemPictureGridHolder holder, int position) {

                boolean isShowCamera = picturePicker.getPickPictureOptions().isShowCamera();
                boolean isMultiMode = picturePicker.getPickPictureOptions().isMultiMode();
                boolean isCanPreviewImg = picturePicker.getPickPictureOptions().isCanPreviewImg();

                if (position == 0 && isShowCamera) {
                    openCamera();
                } else {
                    int realPosition = isShowCamera ? position - 1 : position;
                    if (isMultiMode) {
                        if (isCanPreviewImg) {
                            PicturePreviewActivity.startActivity(PictureGridActivity.this, currentPictureItemList, realPosition, PreviewAction.PREVIEW_PICK, PREVIEW_IMAGE_REQUEST_CODE);
                        } else {
                            pictureGridAdapter.addOrRemovePicture(currentPictureItemList.get(realPosition), holder);
                        }
                    } else {
                        picturePicker.addOrRemovePicture(currentPictureItemList.get(realPosition), true);
                        setResult();
                    }
                }
            }
        });
    }


    /**
     * 打开相机
     */
    private void openCamera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (intent.resolveActivity(getPackageManager()) != null) {
            takePhotoPath = Utils.createTakePhotoPath(this);
            File file = new File(takePhotoPath);
            Uri uri = null;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                uri = FileProvider.getUriForFile(this, getPackageName() + ".FileProvider", file);
            } else {
                uri = Uri.fromFile(file);
            }

            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

            startActivityForResult(intent, OPEN_CAMERA_REQUEST_CODE);
        } else {
            Utils.showToast(this, getResources().getString(R.string.no_camera));
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //拍照返回
        if (requestCode == OPEN_CAMERA_REQUEST_CODE) {

            if (resultCode == Activity.RESULT_OK) {
                File file = new File(takePhotoPath);
                PictureItem pictureItem = new PictureItem();
                pictureItem.pictureAbsPath = takePhotoPath;
                pictureItem.pictureSize = file.length();
                pictureItem.pictureName = file.getName();

                //直接返回
                picturePicker.getSelectedPictureList().clear();
                picturePicker.getSelectedPictureList().add(pictureItem);
                setResult();

            } else if (resultCode == Activity.RESULT_CANCELED
                    && picturePicker.getPickPictureOptions().isJustTakePhoto()) {
                finish();
            }

        } else if (requestCode == PREVIEW_IMAGE_REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                setResult();
            } else if (resultCode == Activity.RESULT_CANCELED
                    && picturePicker.getPickPictureOptions().isJustTakePhoto()) {
                finish();
            }
        }
    }


    private void setResult() {
        Intent intent = new Intent();
        intent.putExtra(EXTRA_RESULT_PICK_IMAGES, (Serializable) picturePicker.getSelectedPictureList());
        setResult(Activity.RESULT_OK, intent);
        finish();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("takePhotoPath", takePhotoPath);
        outState.putSerializable("pickPictureOptions", picturePicker.getPickPictureOptions());
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {

        super.onRestoreInstanceState(savedInstanceState);
        takePhotoPath = savedInstanceState.getString("takePhotoPath");
        picturePicker.setPickPictureOptions((PickOptions) savedInstanceState.getSerializable("pickPictureOptions"));
    }

    /**
     * 初始化展示文件夹列表的popupWindow
     */
    private ListPopupWindow initFolderListPopupWindow() {

        listPopupWindow = new ListPopupWindow(this);
        listPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
        //ListPopupWindow总会相对于这个View 锚点
        listPopupWindow.setAnchorView(llFootBar);
        listPopupWindow.setDropDownGravity(Gravity.BOTTOM);
        //是否为模态，影响返回键的处理
        listPopupWindow.setModal(true);
        listPopupWindow.setContentWidth(ListPopupWindow.MATCH_PARENT);
        listPopupWindow.setWidth(ListPopupWindow.MATCH_PARENT);

        folderListAdapter = new PopupFolderListAdapter(this, pictureFolderList);
        listPopupWindow.setAdapter(folderListAdapter);

        listPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                Utils.setActivityBackgroundAlpha(PictureGridActivity.this, 1.0f);
            }
        });

        listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                PictureFolder pictureFolder = pictureFolderList.get(position);
                if (!TextUtils.equals(pictureFolder.folderAbsPath, folderListAdapter.getCurrentSelectFolderPath())) {
                    folderListAdapter.notifyDataSetChanged(pictureFolder.folderAbsPath);
                    //更新底部文件夹名称
                    setBtnImgFolderText(pictureFolder.folderName);
                    //更新显示的图片
                    notifyPictureGrid(pictureFolder.pictureItemList);
                }

                listPopupWindow.dismiss();
            }
        });

        return listPopupWindow;
    }


    /**
     * 扫描图片
     */
    private void scanAllPictureFolder() {

        if (pictureScanner == null) {
            pictureScanner = new PictureScanner();
        }

        pictureScanner.startScanPicture(this, new PictureScanner.OnScanFinishListener() {
            @Override
            public void onScanFinish(List<PictureFolder> pictureFolders) {
                pictureFolderList.clear();
                pictureFolderList.addAll(pictureFolders);

                if (pictureFolderList.size() > 0) {
                    notifyPictureGrid(pictureFolderList.get(0).pictureItemList);
                    setBtnImgFolderText(pictureFolderList.get(0).folderName);
                    if (folderListAdapter!=null) {
                        folderListAdapter.notifyDataSetChanged(pictureFolderList.get(0).folderAbsPath);
                    }
                } else {
                    currentPictureItemList.clear();
                    notifyPictureGrid(currentPictureItemList);
                    setBtnImgFolderText(null);
                }

            }
        });

    }

    /**
     * 刷新图片ui
     *
     * @param pictureItemList
     */
    private void notifyPictureGrid(List<PictureItem> pictureItemList) {

        if (currentPictureItemList != pictureItemList) {
            currentPictureItemList.clear();
            currentPictureItemList.addAll(pictureItemList);
        }

        pictureGridAdapter.notifyDataSetChanged();
        rvPictures.scrollToPosition(0);
    }


    /**
     * 设置底部当目录名称
     */
    private void setBtnImgFolderText(String folderName) {
        if (TextUtils.isEmpty(folderName)) {
            btnImgFolder.setText(getString(R.string.all_pictures));
            btnImgFolder.setEnabled(false);
        } else {
            btnImgFolder.setText(folderName);
            btnImgFolder.setEnabled(true);
        }
    }

    /**
     * 刷新底部预览图片的数量
     *
     * @param count
     */
    private void refreshPreviewPictureCount(int count) {
        if (count > 0) {
            btnImgPreview.setText(String.format(getString(R.string.preview_button_enable_true), count + ""));
            btnImgPreview.setEnabled(true);
        } else {
            btnImgPreview.setText(getString(R.string.preview_button_enable_false));
            btnImgPreview.setEnabled(false);
        }
    }

    /**
     * 设置titleBar 右边的完成按钮的文本
     *
     * @param count
     */
    private void refreshTitleBarCompleteBtnText(int count) {
        if (count > 0) {
            titleBarHelper.getCompleteButton().setText(String.format(getString(R.string.complete_button_enable_true), count + "", picturePicker.getPickPictureOptions().getPickMaxCount() + ""));
            titleBarHelper.getCompleteButton().setEnabled(true);
        } else {
            titleBarHelper.getCompleteButton().setText(getString(R.string.complete_button_enable_false));
            titleBarHelper.getCompleteButton().setEnabled(false);
        }
    }


    @Override
    public void onClick(View v) {

        int i = v.getId();
        if (i == R.id.btn_img_folder) {
            showFolderListPopupWindow();
        } else if (i == R.id.btn_img_preview) {
            PicturePreviewActivity.startActivity(this, picturePicker.getSelectedPictureList(), 0, PreviewAction.PREVIEW_PICK, PREVIEW_IMAGE_REQUEST_CODE);
        }
    }

    /**
     * 展示文件夹列表的popupWindow
     */
    private void showFolderListPopupWindow() {

        int itemViewHeight = folderListAdapter.getItemViewHeight();
        int maxHeight = rvPictures.getHeight() - itemViewHeight / 2;
        int realHeight = itemViewHeight * folderListAdapter.getCount();
        listPopupWindow.setHeight(Math.min(maxHeight, realHeight));
        Utils.setActivityBackgroundAlpha(PictureGridActivity.this, 0.5f);
        listPopupWindow.show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (pictureScanner != null) {
            pictureScanner.stopScanPicture();
        }
        picturePicker.unregisterPictureSelectedListener(this);
        picturePicker.cleanData();
        Glide.get(this).clearMemory();
    }

    @Override
    public void onPictureSelected(List<PictureItem> selectedPictureList, PictureItem pictureItem, boolean isSelected) {
        refreshTitleBarCompleteBtnText(selectedPictureList.size());
        refreshPreviewPictureCount(selectedPictureList.size());
        pictureGridAdapter.notifyDataSetChanged();
    }
} public class PicturePreviewActivity extends PictureBaseActivity implements PicturePicker.OnPictureSelectedListener {

    public static final String EXTRA_RESULT_PREVIEW_IMAGES = "extra_result_preview_pictures";


    /**
     * 因为intent不能传递大数据，故对于大集合数据 采用static 赋值方式
     */
    private static List<PictureItem> toLargePictureItems;

    private List<PictureItem> pictureItemList;
    private PicturePicker picturePicker;

    private View titleBar;
    private TextView titleTextView;
    private Button titleCompleteButton;
    private ImageView ivDelete;


    private LinearLayout llFootBar;
    private TextView tvPicturePreviewSelect;

    private PreviewAction previewAction;
    protected PreviewPictureFragment pictureFragment;


    /**
     * 只预览图片
     *
     * @param activity
     * @param url
     */
    public static void startActivityWithOnlyPreview(Activity activity, String url) {
        List<PictureItem> pictureItems = new ArrayList<>();
        PictureItem pictureItem = new PictureItem();
        pictureItem.pictureAbsPath = url;
        pictureItems.add(pictureItem);

        startActivityWithOnlyPreview(activity, pictureItems, 0);
    }

    /**
     * 只预览图片
     *
     * @param activity
     * @param urls
     * @param currPosition
     */
    public static void startActivityWithOnlyPreview(Activity activity, int currPosition, List<String> urls) {
        List<PictureItem> pictureItems = new ArrayList<>();
        for (String url : urls) {
            PictureItem pictureItem = new PictureItem();
            pictureItem.pictureAbsPath = url;
            pictureItems.add(pictureItem);
        }
        startActivityWithOnlyPreview(activity, pictureItems, currPosition);
    }


    /**
     * 只预览图片
     *
     * @param activity
     * @param pictureItems
     * @param currPosition
     */
    public static void startActivityWithOnlyPreview(Activity activity, List<PictureItem> pictureItems, int currPosition) {
        Intent intent = createIntent(activity, pictureItems, currPosition, PreviewAction.ONLY_PREVIEW);
        activity.startActivity(intent);
    }


    /**
     * 预览可删除
     *
     * @param fragment     android.app.Fragment fragment
     * @param urls         图片url list
     * @param currPosition 开始预览的index
     * @param requestCode  请求码
     */
    public static void startActivityWithPreviewDel(android.app.Fragment fragment, List<String> urls, int currPosition, int requestCode) {
        List<PictureItem> pictureItems = new ArrayList<>();
        for (String url : urls) {
            PictureItem pictureItem = new PictureItem();
            pictureItem.pictureAbsPath = url;
            pictureItems.add(pictureItem);
        }
        Intent intent = createIntent(fragment.getActivity(), pictureItems, currPosition, PreviewAction.PREVIEW_DELETE);
        fragment.startActivityForResult(intent, requestCode);
    }

    /**
     * 预览可删除
     *
     * @param fragment     android.support.v4.app.Fragment fragment
     * @param urls         图片url list
     * @param currPosition 开始预览的index
     * @param requestCode  请求码
     */
    public static void startActivityWithPreviewDel(android.support.v4.app.Fragment fragment, List<String> urls, int currPosition, int requestCode) {
        List<PictureItem> pictureItems = new ArrayList<>();
        for (String url : urls) {
            PictureItem pictureItem = new PictureItem();
            pictureItem.pictureAbsPath = url;
            pictureItems.add(pictureItem);
        }
        Intent intent = createIntent(fragment.getActivity(), pictureItems, currPosition, PreviewAction.PREVIEW_DELETE);
        fragment.startActivityForResult(intent, requestCode);
    }

    /**
     * 预览可删除
     *
     * @param activity     activity
     * @param urls         图片url list
     * @param currPosition 开始预览的index
     * @param requestCode  请求码
     */
    public static void startActivityWithPreviewDel(Activity activity, List<String> urls, int currPosition, int requestCode) {
        List<PictureItem> pictureItems = new ArrayList<>();
        for (String url : urls) {
            PictureItem pictureItem = new PictureItem();
            pictureItem.pictureAbsPath = url;
            pictureItems.add(pictureItem);
        }
        Intent intent = createIntent(activity, pictureItems, currPosition, PreviewAction.PREVIEW_DELETE);
        activity.startActivityForResult(intent, requestCode);
    }


    /**
     * 使用者一般用不上此方法
     *
     * @param activity     activity
     * @param pictureItems PictureItem list
     * @param currPosition 开始预览的index
     * @param action       打开本页面的意图
     * @param requestCode  请求码
     */
    public static void startActivity(Activity activity, List<PictureItem> pictureItems, int currPosition, PreviewAction action, int requestCode) {
        Intent intent = createIntent(activity, pictureItems, currPosition, action);
        activity.startActivityForResult(intent, requestCode);
    }

    private static Intent createIntent(Context context, List<PictureItem> pictureItems, int currPosition, PreviewAction action) {
        Intent intent = new Intent(context, getClazz());
        intent.putExtra("currPosition", currPosition);
        intent.putExtra("previewAction", action);

        if (pictureItems.size() > 1000) {
            toLargePictureItems = pictureItems;
        } else {
            intent.putExtra("pictureItems", (Serializable) pictureItems);
        }
        return intent;
    }


    protected static Class<? extends PicturePreviewActivity> getClazz() {
        return PicturePreviewActivity.class;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_picture_preview);
        assignViews();

        picturePicker = PicturePicker.getInstance();

        previewAction = (PreviewAction) getIntent().getSerializableExtra("previewAction");
        initTitleBarAndFootBar(previewAction);

        int currPosition = getIntent().getIntExtra("currPosition", 0);
        pictureItemList = (List<PictureItem>) getIntent().getSerializableExtra("pictureItems");
        if (pictureItemList == null) {
            pictureItemList = toLargePictureItems;
            toLargePictureItems = null;
        }
        pictureFragment = (PreviewPictureFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
        int i = titleBar.getLayoutParams().height + Utils.getStatusHeight(this);
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) pictureFragment.getView().getLayoutParams();
        layoutParams.topMargin = -i;

        pictureFragment.setPictureItems(pictureItemList, currPosition);

        if (currPosition < pictureItemList.size()) {
            refreshTitleText(currPosition + 1, pictureItemList.size());
            tvPicturePreviewSelect.setSelected(picturePicker.isSelected(pictureItemList.get(currPosition)));
        }

        if (previewAction == PreviewAction.ONLY_PREVIEW) {
            fullScreen(true);
        }
        setListener();
        picturePicker.registerPictureSelectedListener(this);

    }

    private void assignViews() {
        llFootBar = (LinearLayout) findViewById(R.id.ll_foot_bar);
        tvPicturePreviewSelect = (TextView) findViewById(R.id.tv_picture_preview_select);
    }

    private void setListener() {

        pictureFragment.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                refreshTitleText(position + 1, pictureItemList.size());
                PictureItem pictureItem = pictureItemList.get(position);
                tvPicturePreviewSelect.setSelected(picturePicker.isSelected(pictureItem));
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });
        pictureFragment.setOnPictureClickListener(new PicturePreviewAdapter.OnPictureClickListener() {
            @Override
            public void onPictureClick(int position, String url) {
                fullScreen(titleBar.getVisibility() == View.VISIBLE);
            }
        });

        titleCompleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setResult(RESULT_OK);
                finish();
            }
        });

        ivDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                new AlertDialog.Builder(PicturePreviewActivity.this)
                        .setTitle(R.string.del_dialog_title)
                        .setMessage(R.string.del_dialog_msg)
                        .setCancelable(true)
                        .setPositiveButton(R.string.del_dialog_positive_button, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                                if (pictureItemList.size() == 1) {
                                    pictureItemList.remove(pictureFragment.getCurrentItem());
                                    setResultOnPreviewDelete();
                                    finish();
                                } else {
                                    pictureItemList.remove(pictureFragment.getCurrentItem());
                                    refreshTitleText(pictureFragment.getCurrentItem() + 1, pictureItemList.size());
                                    pictureFragment.setPictureItems(pictureItemList, pictureFragment.getCurrentItem());
                                }
                            }
                        })
                        .setNegativeButton(R.string.del_dialog_negative_button, null)
                        .show();
            }
        });


        tvPicturePreviewSelect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (pictureItemList.size() > 0) {
                    PictureItem pictureItem = pictureItemList.get(pictureFragment.getCurrentItem());
                    boolean isSelected = picturePicker.isSelected(pictureItem);

                    if (isSelected) {
                        tvPicturePreviewSelect.setSelected(false);
                        picturePicker.addOrRemovePicture(pictureItem, false);
                    } else {
                        int maxCount = picturePicker.getPickPictureOptions().getPickMaxCount();
                        if (picturePicker.getCurrentSelectedCount() >= maxCount) {
                            Utils.showToast(v.getContext(), v.getContext().getResources().getString(R.string.select_limit_tips, maxCount + ""));
                        } else {
                            tvPicturePreviewSelect.setSelected(true);
                            picturePicker.addOrRemovePicture(pictureItem, true);
                        }
                    }
                }
            }
        });

    }

    @Override
    protected void resetTitleBar(TitleBarHelper titleBarHelper) {

        titleBarHelper.getBackImageView().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                setResultOnPreviewDelete();
                finish();
            }
        });

        titleBar = titleBarHelper.getTitleBarView();

        titleTextView = titleBarHelper.getTitleTextView();
        refreshTitleText(0, 0);

        titleCompleteButton = titleBarHelper.getCompleteButton();
        ivDelete = titleBarHelper.getIvDelete();

    }

    /**
     * 根据行为初始化titleBar和footBar
     *
     * @param action
     */
    private void initTitleBarAndFootBar(PreviewAction action) {

        switch (action) {
            case ONLY_PREVIEW:
                titleCompleteButton.setVisibility(View.GONE);
                ivDelete.setVisibility(View.GONE);
                llFootBar.setVisibility(View.GONE);
                break;
            case PREVIEW_PICK:
                titleCompleteButton.setVisibility(View.VISIBLE);
                refreshTitleCompleteButton();
                ivDelete.setVisibility(View.GONE);
                llFootBar.setVisibility(View.VISIBLE);
                break;
            case PREVIEW_DELETE:
                titleCompleteButton.setVisibility(View.GONE);
                ivDelete.setVisibility(View.VISIBLE);
                llFootBar.setVisibility(View.GONE);
                break;
            default:
                break;
        }
    }

    private void refreshTitleText(int position, int size) {
        titleTextView.setText(getString(R.string.img_preview_count, position + "", size + ""));
    }

    /**
     * 刷新titleBar的完成按钮
     */
    private void refreshTitleCompleteButton() {
        if (previewAction == PreviewAction.PREVIEW_PICK) {
            int currentSelectedCount = picturePicker.getCurrentSelectedCount();
            int maxCount = picturePicker.getPickPictureOptions().getPickMaxCount();
            if (currentSelectedCount == 0) {
                titleCompleteButton.setEnabled(false);
                titleCompleteButton.setText(getString(R.string.complete_button_enable_false));
            } else {
                titleCompleteButton.setEnabled(true);
                titleCompleteButton.setText(getString(R.string.complete_button_enable_true, currentSelectedCount + "", maxCount + ""));
            }
        }
    }

    @Override
    public void onPictureSelected(List<PictureItem> selectedPictureList, PictureItem pictureItem, boolean isSelected) {
        refreshTitleCompleteButton();
    }


    /**
     * 是否全屏显示图片
     *
     * @param enable
     */
    private void fullScreen(boolean enable) {

        if (enable) {
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) pictureFragment.getView().getLayoutParams();
            layoutParams.topMargin = 0;
            titleBar.setVisibility(View.GONE);
            Utils.hideStatusBar(this, true);
            llFootBar.setVisibility(View.GONE);
        } else {
            Utils.hideStatusBar(this, false);
            int i = titleBar.getLayoutParams().height + Utils.getStatusHeight(PicturePreviewActivity.this);
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) pictureFragment.getView().getLayoutParams();
            layoutParams.topMargin = -i;
            titleBar.setVisibility(View.VISIBLE);
            if (previewAction == PreviewAction.PREVIEW_PICK) {
                llFootBar.setVisibility(View.VISIBLE);
            }
        }

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        picturePicker.unregisterPictureSelectedListener(this);
        Glide.get(this).clearMemory();
    }

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

    private void setResultOnPreviewDelete() {
        if (previewAction == PreviewAction.PREVIEW_DELETE) {
            Intent intent = new Intent();
            intent.putExtra(EXTRA_RESULT_PREVIEW_IMAGES, (Serializable) pictureItemList);
            setResult(RESULT_OK, intent);
        }
    }
} public enum PreviewAction implements Serializable {

    /**
     * 只预览
     */
    ONLY_PREVIEW,
    /**
     * 预览并选择图库相片
     */
    PREVIEW_PICK,
    /**
     * 预览并可删除图片
     */
    PREVIEW_DELETE


} public class PictureItem implements Serializable {

    /**
     * 图片名称
     */
    public String pictureName;
    /**
     * 图片绝对路径
     */
    public String pictureAbsPath;
    /**
     * 图片类型
     */
    public String pictureMimeType;
    /**
     * 图片大小
     */
    public long pictureSize;
    /**
     * 图片加入的时间
     */
    public long pictureAddTime;
    /**
     * 图片的宽
     */
    public int pictureWidth;
    /**
     * 图片的高
     */
    public int pictureHeight;


    @Override
    public boolean equals(Object o) {
        if (o instanceof PictureItem) {
            PictureItem pictureItem = ((PictureItem) o);
            return TextUtils.equals(pictureItem.pictureAbsPath, pictureAbsPath)
                    &&
                    pictureItem.pictureAddTime == pictureAddTime;
        }
        return super.equals(o);
    }
} public class CropOptions implements Serializable {

    private int outPutX;
    private int outPutY;
    private CropImageView.Style style;
    private int focusWidth;
    private int focusHeight;
    private boolean isSaveRectangle;

    private CropOptions(Builder builder) {
        outPutX = builder.outPutX;
        outPutY = builder.outPutY;
        style = builder.style;
        focusWidth = builder.focusWidth;
        focusHeight = builder.focusHeight;
        isSaveRectangle = builder.isSaveRectangle;
    }

    public int getOutPutX() {
        return outPutX;
    }

    public int getOutPutY() {
        return outPutY;
    }

    public CropImageView.Style getStyle() {
        return style;
    }

    public int getFocusWidth() {
        return focusWidth;
    }

    public int getFocusHeight() {
        return focusHeight;
    }

    public boolean isSaveRectangle() {
        return isSaveRectangle;
    }

    public static class Builder implements Serializable {

        private int outPutX=800;
        private int outPutY=800;
        private CropImageView.Style style=CropImageView.Style.RECTANGLE;
        private int focusWidth=280;
        private int focusHeight=280;
        private boolean isSaveRectangle=false;

        public Builder() {
        }

        public CropOptions build() {
            return new CropOptions(this);
        }


        /**
         * 裁剪后需要保存的图片宽度
         *
         * @param outPutX
         */
        public Builder setOutPutX(int outPutX) {
            this.outPutX = outPutX;
            return this;
        }

        /**
         * 裁剪后需要保存的图片宽度
         *
         * @param outPutY
         */
        public Builder setOutPutY(int outPutY) {
            this.outPutY = outPutY;
            return this;
        }

        /**
         * 裁剪时，裁剪框是矩形还是圆形
         *
         * @param style
         */
        public Builder setStyle(CropImageView.Style style) {
            this.style = style;
            return this;
        }

        /**
         * 矩形裁剪框宽度（圆形自动取宽高最小值）
         *
         * @param focusWidth
         */
        public Builder setFocusWidth(int focusWidth) {
            this.focusWidth = focusWidth;
            return this;
        }

        /**
         * 矩形裁剪框高度（圆形自动取宽高最小值）
         *
         * @param focusHeight
         */
        public Builder setFocusHeight(int focusHeight) {
            this.focusHeight = focusHeight;
            return this;
        }

        /**
         * 裁剪后的图片是按矩形区域保存还是裁剪框的形状，
         * 例如圆形裁剪的时候，该参数给true，那么保存的图片是矩形区域，
         * 如果该参数给false，保存的图片是圆形区域
         *
         * @param saveRectangle
         */
        public Builder setSaveRectangle(boolean saveRectangle) {
            isSaveRectangle = saveRectangle;
            return this;
        }
    }


} public class PickOptions implements Serializable {

    private boolean justTakePhoto;
    private int pickMaxCount;
    private boolean multiMode;
    private boolean showCamera;
    private boolean canPreviewImg;
    private boolean selectGif;

    private PickOptions(Builder builder) {
        this.justTakePhoto = builder.justTakePhoto;
        this.pickMaxCount = builder.pickMaxCount;
        this.multiMode = builder.multiMode;
        this.showCamera = builder.showCamera;
        this.canPreviewImg = builder.canPreviewImg;
        this.selectGif = builder.selectGif;
    }

    private PickOptions() {
    }

    public boolean isJustTakePhoto() {
        return justTakePhoto;
    }

    public int getPickMaxCount() {
        return pickMaxCount;
    }

    public boolean isMultiMode() {
        return multiMode;
    }

    public boolean isShowCamera() {
        return showCamera;
    }

    public boolean isCanPreviewImg() {
        return canPreviewImg;
    }

    public boolean isSelectGif() {
        return selectGif;
    }

    public static PickOptions getDefaultOptions() {
        return new PickOptions(new Builder());
    }

    public static class Builder implements Serializable {
        private boolean justTakePhoto=false;
        private int pickMaxCount = 9;
        private boolean multiMode = true;
        private boolean showCamera = true;
        private boolean canPreviewImg = true;
        private boolean selectGif = true;

        public Builder() {
        }

        public PickOptions build() {
            return new PickOptions(this);
        }

        public Builder setJustTakePhoto(boolean justTakePhoto) {
            this.justTakePhoto = justTakePhoto;
            return this;
        }

        public Builder setPickMaxCount(int pickMaxCount) {
            this.pickMaxCount = pickMaxCount;
            return this;
        }

        public Builder setMultiMode(boolean multiMode) {
            this.multiMode = multiMode;
            return this;
        }

        public Builder setShowCamera(boolean showCamera) {
            this.showCamera = showCamera;
            return this;
        }

        public Builder setCanPreviewImg(boolean canPreviewImg) {
            this.canPreviewImg = canPreviewImg;
            return this;
        }

        public Builder setSelectGif(boolean selectGif) {
            this.selectGif = selectGif;
            return this;
        }
    }

} public class PicturePicker {

    private ILanguageProvider languageProvider;


    private List<OnPictureSelectedListener> pictureSelectedListeners = new ArrayList<>();
    private List<PictureItem> selectedPictureList = new ArrayList<>();

    private static PicturePicker picturePicker;
    private PickOptions pickPictureOptions;

    private PicturePicker() {
    }

    public static PicturePicker getInstance() {
        if (picturePicker == null) {
            synchronized (PicturePicker.class) {
                if (picturePicker == null) {
                    picturePicker = new PicturePicker();
                }
            }
        }

        return picturePicker;
    }


    /**
     * 默认配置下选择图片
     *
     * @param activity
     * @param requestCode
     */
    public void startPickPicture(Activity activity, int requestCode) {
        startPickPicture(activity, requestCode, PickOptions.getDefaultOptions());
    }

    /**
     * @param activity
     * @param requestCode
     * @param options     选择图片时的配置
     */
    public void startPickPicture(Activity activity, int requestCode, PickOptions options) {

        this.pickPictureOptions = options;
        Intent intent = new Intent(activity, CheckPermissionActivity.class);
        activity.startActivityForResult(intent, requestCode);

    }

    public void startPickPicture(android.app.Fragment fragment, int requestCode) {
        startPickPicture(fragment, requestCode, PickOptions.getDefaultOptions());
    }

    public void startPickPicture(android.app.Fragment fragment, int requestCode, PickOptions options) {
        this.pickPictureOptions = options;
        Intent intent = new Intent(fragment.getActivity(), CheckPermissionActivity.class);
        fragment.startActivityForResult(intent, requestCode);
    }

    public void startPickPicture(android.support.v4.app.Fragment fragment, int requestCode) {
        startPickPicture(fragment, requestCode, PickOptions.getDefaultOptions());
    }

    public void startPickPicture(android.support.v4.app.Fragment fragment, int requestCode, PickOptions options) {
        this.pickPictureOptions = options;
        Intent intent = new Intent(fragment.getActivity(), CheckPermissionActivity.class);
        fragment.startActivityForResult(intent, requestCode);
    }



    /**
     * 清理数据
     */
    public void cleanData() {
        pictureSelectedListeners.clear();
        selectedPictureList.clear();
        pickPictureOptions=null;
    }


    /**
     * 获取当前的选择配置
     * @return
     */
    public PickOptions getPickPictureOptions() {
        return pickPictureOptions;
    }

    public void setPickPictureOptions(PickOptions pickPictureOptions) {
        this.pickPictureOptions = pickPictureOptions;
    }

    /**
     * 获取当前已经选择的图片
     * @return
     */
    public  List<PictureItem> getSelectedPictureList(){
        return selectedPictureList;
    }


    /**
     * 判断某个图片是否被选中
     *
     * @param pictureItem
     * @return
     */
    public boolean isSelected(PictureItem pictureItem) {
        return selectedPictureList.contains(pictureItem);
    }

    /**
     * 获取当前已经选择的图片的数量
     * @return
     */
    public int getCurrentSelectedCount() {
        return selectedPictureList.size();
    }


    public void addOrRemovePicture(PictureItem pictureItem, boolean isSelected) {

        if (isSelected) {
            selectedPictureList.add(pictureItem);
        } else {
            selectedPictureList.remove(pictureItem);
        }

        for (OnPictureSelectedListener listener : pictureSelectedListeners) {
            listener.onPictureSelected(selectedPictureList, pictureItem, isSelected);
        }

    }

    /**
     * 图片选择的监听
     */
    public interface OnPictureSelectedListener {
        void onPictureSelected(List<PictureItem> selectedPictureList, PictureItem pictureItem, boolean isSelected);
    }

    /**
     * 注册图片选择的监听器
     *
     * @param listener
     */
    public void registerPictureSelectedListener(OnPictureSelectedListener listener) {
        if (listener != null) {
            pictureSelectedListeners.add(listener);
        }
    }

    /**
     * 反注册图片选择的监听器
     *
     * @param listener
     */
    public void unregisterPictureSelectedListener(OnPictureSelectedListener listener) {
        if (listener != null) {
            pictureSelectedListeners.remove(listener);
        }
    }

    public ILanguageProvider getLanguageProvider() {
        return languageProvider;
    }

    public void setLanguageProvider(ILanguageProvider languageProvider) {
        this.languageProvider = languageProvider;
    }
} public class ImageLoader {

    public static void load(Context context, String path, ImageView imageView) {
        RequestOptions requestOptions =
                new RequestOptions()
                        .placeholder(R.drawable.default_picture)
                        .error(R.drawable.default_picture);
        Glide.with(context)
                .load(path)
                .apply(requestOptions)
                .into(imageView);

    }
} public class PictureLangUtils {

    public static Context setLanguage(Context context, Locale locale) {

        Resources resources = context.getResources();
        Configuration config = resources.getConfiguration();
        config.setLocale(locale);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            LocaleList localeList = new LocaleList(locale);
            LocaleList.setDefault(localeList);
            config.setLocales(localeList);
            return context.createConfigurationContext(config);
        } else {
            DisplayMetrics displayMetrics = resources.getDisplayMetrics();
            context.getResources().updateConfiguration(config, displayMetrics);
            return context;
        }
    }
} public class CropImageView extends AppCompatImageView {

    /******************************** 中间的FocusView绘图相关的参数 *****************************/
    public enum Style {
        RECTANGLE, CIRCLE
    }

    private Style[] styles = {Style.RECTANGLE, Style.CIRCLE};

    private int mMaskColor = 0xAF000000;   //暗色
    private int mBorderColor = 0xAA808080; //焦点框的边框颜色
    private int mBorderWidth = 1;         //焦点边框的宽度（画笔宽度）
    private int mFocusWidth = 250;         //焦点框的宽度
    private int mFocusHeight = 250;        //焦点框的高度
    private int mDefaultStyleIndex = 0;    //默认焦点框的形状

    private Style mStyle = styles[mDefaultStyleIndex];
    private Paint mBorderPaint = new Paint();
    private Path mFocusPath = new Path();
    private RectF mFocusRect = new RectF();

    /******************************** 图片缩放位移控制的参数 ************************************/
    private static final float MAX_SCALE = 4.0f;  //最大缩放比，图片缩放后的大小与中间选中区域的比值
    private static final int NONE = 0;   // 初始化
    private static final int DRAG = 1;   // 拖拽
    private static final int ZOOM = 2;   // 缩放
    private static final int ROTATE = 3; // 旋转
    private static final int ZOOM_OR_ROTATE = 4;  // 缩放或旋转

    private static final int SAVE_SUCCESS = 1001;  // 缩放或旋转
    private static final int SAVE_ERROR = 1002;  // 缩放或旋转

    private int mImageWidth;
    private int mImageHeight;
    private int mRotatedImageWidth;
    private int mRotatedImageHeight;
    private Matrix matrix = new Matrix();      //图片变换的matrix
    private Matrix savedMatrix = new Matrix(); //开始变幻的时候，图片的matrix
    private PointF pA = new PointF();          //第一个手指按下点的坐标
    private PointF pB = new PointF();          //第二个手指按下点的坐标
    private PointF midPoint = new PointF();    //两个手指的中间点
    private PointF doubleClickPos = new PointF();  //双击图片的时候，双击点的坐标
    private PointF mFocusMidPoint = new PointF();  //中间View的中间点
    private int mode = NONE;            //初始的模式
    private long doubleClickTime = 0;   //第二次双击的时间
    private double rotation = 0;        //手指旋转的角度，不是90的整数倍，可能为任意值，需要转换成level
    private float oldDist = 1;          //双指第一次的距离
    private int sumRotateLevel = 0;     //旋转的角度，90的整数倍
    private float mMaxScale = MAX_SCALE;//程序根据不同图片的大小，动态得到的最大缩放比
    private boolean isInited = false;   //是否经过了 onSizeChanged 初始化
    private boolean mSaving = false;    //是否正在保存
    private  Handler mHandler = new InnerHandler();

    public CropImageView(Context context) {
        this(context, null);
    }

    public CropImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CropImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mFocusWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mFocusWidth, getResources().getDisplayMetrics());
        mFocusHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mFocusHeight, getResources().getDisplayMetrics());
        mBorderWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mBorderWidth, getResources().getDisplayMetrics());

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CropImageView);
        mMaskColor = a.getColor(R.styleable.CropImageView_cropMaskColor, mMaskColor);
        mBorderColor = a.getColor(R.styleable.CropImageView_cropBorderColor, mBorderColor);
        mBorderWidth = a.getDimensionPixelSize(R.styleable.CropImageView_cropBorderWidth, mBorderWidth);
        mFocusWidth = a.getDimensionPixelSize(R.styleable.CropImageView_cropFocusWidth, mFocusWidth);
        mFocusHeight = a.getDimensionPixelSize(R.styleable.CropImageView_cropFocusHeight, mFocusHeight);
        mDefaultStyleIndex = a.getInteger(R.styleable.CropImageView_cropStyle, mDefaultStyleIndex);
        mStyle = styles[mDefaultStyleIndex];
        a.recycle();

        setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        //只允许图片为当前的缩放模式
        setScaleType(ScaleType.MATRIX);
    }

    @Override
    public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        initImage();
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        super.setImageDrawable(drawable);
        initImage();
    }

    @Override
    public void setImageResource(int resId) {
        super.setImageResource(resId);
        initImage();
    }

    @Override
    public void setImageURI(Uri uri) {
        super.setImageURI(uri);
        initImage();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        isInited = true;
        initImage();
    }

    /**
     * 初始化图片和焦点框
     */
    private void initImage() {
        Drawable d = getDrawable();
        if (!isInited || d == null) return;

        mode = NONE;
        matrix = getImageMatrix();
        mImageWidth = mRotatedImageWidth = d.getIntrinsicWidth();
        mImageHeight = mRotatedImageHeight = d.getIntrinsicHeight();
        //计算出焦点框的中点的坐标和上、下、左、右边的x或y的值
        int viewWidth = getWidth();
        int viewHeight = getHeight();
        float midPointX = viewWidth / 2;
        float midPointY = viewHeight / 2;
        mFocusMidPoint = new PointF(midPointX, midPointY);

        if (mStyle == Style.CIRCLE) {
            int focusSize = Math.min(mFocusWidth, mFocusHeight);
            mFocusWidth = focusSize;
            mFocusHeight = focusSize;
        }
        mFocusRect.left = mFocusMidPoint.x - mFocusWidth / 2;
        mFocusRect.right = mFocusMidPoint.x + mFocusWidth / 2;
        mFocusRect.top = mFocusMidPoint.y - mFocusHeight / 2;
        mFocusRect.bottom = mFocusMidPoint.y + mFocusHeight / 2;

        //适配焦点框的缩放比例（图片的最小边不小于焦点框的最小边）
        float fitFocusScale = getScale(mImageWidth, mImageHeight, mFocusWidth, mFocusHeight, true);
        mMaxScale = fitFocusScale * MAX_SCALE;
        //适配显示图片的ImageView的缩放比例（图片至少有一边是铺满屏幕的显示的情形）
        float fitViewScale = getScale(mImageWidth, mImageHeight, viewWidth, viewHeight, false);
        //确定最终的缩放比例,在适配焦点框的前提下适配显示图片的ImageView，
        //方案：首先满足适配焦点框，如果还能适配显示图片的ImageView，则适配它，即取缩放比例的最大值。
        //采取这种方案的原因：有可能图片很长或者很高，适配了ImageView的时候可能会宽/高已经小于焦点框的宽/高
        float scale = fitViewScale > fitFocusScale ? fitViewScale : fitFocusScale;
        //图像中点为中心进行缩放
        matrix.setScale(scale, scale, mImageWidth / 2, mImageHeight / 2);
        float[] mImageMatrixValues = new float[9];
        matrix.getValues(mImageMatrixValues); //获取缩放后的mImageMatrix的值
        float transX = mFocusMidPoint.x - (mImageMatrixValues[2] + mImageWidth * mImageMatrixValues[0] / 2);  //X轴方向的位移
        float transY = mFocusMidPoint.y - (mImageMatrixValues[5] + mImageHeight * mImageMatrixValues[4] / 2); //Y轴方向的位移
        matrix.postTranslate(transX, transY);
        setImageMatrix(matrix);
        invalidate();
    }

    /**
     * 计算边界缩放比例 isMinScale 是否最小比例，true 最小缩放比例， false 最大缩放比例
     */
    private float getScale(int bitmapWidth, int bitmapHeight, int minWidth, int minHeight, boolean isMinScale) {
        float scale;
        float scaleX = (float) minWidth / bitmapWidth;
        float scaleY = (float) minHeight / bitmapHeight;
        if (isMinScale) {
            scale = scaleX > scaleY ? scaleX : scaleY;
        } else {
            scale = scaleX < scaleY ? scaleX : scaleY;
        }
        return scale;
    }

    /**
     * 绘制焦点框
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (Style.RECTANGLE == mStyle) {
            mFocusPath.addRect(mFocusRect, Path.Direction.CCW);
            canvas.save();
            canvas.clipRect(0, 0, getWidth(), getHeight());
            canvas.clipPath(mFocusPath, Region.Op.DIFFERENCE);
            canvas.drawColor(mMaskColor);
            canvas.restore();
        } else if (Style.CIRCLE == mStyle) {
            float radius = Math.min((mFocusRect.right - mFocusRect.left) / 2, (mFocusRect.bottom - mFocusRect.top) / 2);
            mFocusPath.addCircle(mFocusMidPoint.x, mFocusMidPoint.y, radius, Path.Direction.CCW);
            canvas.save();
            canvas.clipRect(0, 0, getWidth(), getHeight());
            canvas.clipPath(mFocusPath, Region.Op.DIFFERENCE);
            canvas.drawColor(mMaskColor);
            canvas.restore();
        }
        mBorderPaint.setColor(mBorderColor);
        mBorderPaint.setStyle(Paint.Style.STROKE);
        mBorderPaint.setStrokeWidth(mBorderWidth);
        mBorderPaint.setAntiAlias(true);
        canvas.drawPath(mFocusPath, mBorderPaint);
        mFocusPath.reset();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mSaving || null == getDrawable()) {
            return super.onTouchEvent(event);
        }
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:  //第一个点按下
                savedMatrix.set(matrix);   //以后每次需要变换的时候，以现在的状态为基础进行变换
                pA.set(event.getX(), event.getY());
                pB.set(event.getX(), event.getY());
                mode = DRAG;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:  //第二个点按下
                if (event.getActionIndex() > 1) break;
                pA.set(event.getX(0), event.getY(0));
                pB.set(event.getX(1), event.getY(1));
                midPoint.set((pA.x + pB.x) / 2, (pA.y + pB.y) / 2);
                oldDist = spacing(pA, pB);
                savedMatrix.set(matrix);  //以后每次需要变换的时候，以现在的状态为基础进行变换
                if (oldDist > 10f) mode = ZOOM_OR_ROTATE;//两点之间的距离大于10才有效
                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == ZOOM_OR_ROTATE) {
                    PointF pC = new PointF(event.getX(1) - event.getX(0) + pA.x, event.getY(1) - event.getY(0) + pA.y);
                    double a = spacing(pB.x, pB.y, pC.x, pC.y);
                    double b = spacing(pA.x, pA.y, pC.x, pC.y);
                    double c = spacing(pA.x, pA.y, pB.x, pB.y);
                    if (a >= 10) {
                        double cosB = (a * a + c * c - b * b) / (2 * a * c);
                        double angleB = Math.acos(cosB);
                        double PID4 = Math.PI / 4;
                        //旋转时，默认角度在 45 - 135 度之间
                        if (angleB > PID4 && angleB < 3 * PID4) mode = ROTATE;
                        else mode = ZOOM;
                    }
                }
                if (mode == DRAG) {
                    matrix.set(savedMatrix);
                    matrix.postTranslate(event.getX() - pA.x, event.getY() - pA.y);
                    fixTranslation();
                    setImageMatrix(matrix);
                } else if (mode == ZOOM) {
                    float newDist = spacing(event.getX(0), event.getY(0), event.getX(1), event.getY(1));
                    if (newDist > 10f) {
                        matrix.set(savedMatrix);
                        // 这里之所以用 maxPostScale 矫正一下，主要是防止缩放到最大时，继续缩放图片会产生位移
                        float tScale = Math.min(newDist / oldDist, maxPostScale());
                        if (tScale != 0) {
                            matrix.postScale(tScale, tScale, midPoint.x, midPoint.y);
                            fixScale();
                            fixTranslation();
                            setImageMatrix(matrix);
                        }
                    }
                } else if (mode == ROTATE) {
                    PointF pC = new PointF(event.getX(1) - event.getX(0) + pA.x, event.getY(1) - event.getY(0) + pA.y);
                    double a = spacing(pB.x, pB.y, pC.x, pC.y);
                    double b = spacing(pA.x, pA.y, pC.x, pC.y);
                    double c = spacing(pA.x, pA.y, pB.x, pB.y);
                    if (b > 10) {
                        double cosA = (b * b + c * c - a * a) / (2 * b * c);
                        double angleA = Math.acos(cosA);
                        double ta = pB.y - pA.y;
                        double tb = pA.x - pB.x;
                        double tc = pB.x * pA.y - pA.x * pB.y;
                        double td = ta * pC.x + tb * pC.y + tc;
                        if (td > 0) {
                            angleA = 2 * Math.PI - angleA;
                        }
                        rotation = angleA;
                        matrix.set(savedMatrix);
                        matrix.postRotate((float) (rotation * 180 / Math.PI), midPoint.x, midPoint.y);
                        setImageMatrix(matrix);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                if (mode == DRAG) {
                    if (spacing(pA, pB) < 50) {
                        long now = System.currentTimeMillis();
                        if (now - doubleClickTime < 500 && spacing(pA, doubleClickPos) < 50) {
                            doubleClick(pA.x, pA.y);
                            now = 0;
                        }
                        doubleClickPos.set(pA);
                        doubleClickTime = now;
                    }
                } else if (mode == ROTATE) {
                    int rotateLevel = (int) Math.floor((rotation + Math.PI / 4) / (Math.PI / 2));
                    if (rotateLevel == 4) rotateLevel = 0;
                    matrix.set(savedMatrix);
                    matrix.postRotate(90 * rotateLevel, midPoint.x, midPoint.y);
                    if (rotateLevel == 1 || rotateLevel == 3) {
                        int tmp = mRotatedImageWidth;
                        mRotatedImageWidth = mRotatedImageHeight;
                        mRotatedImageHeight = tmp;
                    }
                    fixScale();
                    fixTranslation();
                    setImageMatrix(matrix);
                    sumRotateLevel += rotateLevel;
                }
                mode = NONE;
                break;
        }
        //解决部分机型无法拖动的问题
        ViewCompat.postInvalidateOnAnimation(this);
        return true;
    }

    /**
     * 修正图片的缩放比
     */
    private void fixScale() {
        float imageMatrixValues[] = new float[9];
        matrix.getValues(imageMatrixValues);
        float currentScale = Math.abs(imageMatrixValues[0]) + Math.abs(imageMatrixValues[1]);
        float minScale = getScale(mRotatedImageWidth, mRotatedImageHeight, mFocusWidth, mFocusHeight, true);
        mMaxScale = minScale * MAX_SCALE;

        //保证图片最小是占满中间的焦点空间
        if (currentScale < minScale) {
            float scale = minScale / currentScale;
            matrix.postScale(scale, scale);
        } else if (currentScale > mMaxScale) {
            float scale = mMaxScale / currentScale;
            matrix.postScale(scale, scale);
        }
    }

    /**
     * 修正图片的位移
     */
    private void fixTranslation() {
        RectF imageRect = new RectF(0, 0, mImageWidth, mImageHeight);
        matrix.mapRect(imageRect);  //获取当前图片（缩放以后的）相对于当前控件的位置区域，超过控件的上边缘或左边缘为负
        float deltaX = 0, deltaY = 0;
        if (imageRect.left > mFocusRect.left) {
            deltaX = -imageRect.left + mFocusRect.left;
        } else if (imageRect.right < mFocusRect.right) {
            deltaX = -imageRect.right + mFocusRect.right;
        }
        if (imageRect.top > mFocusRect.top) {
            deltaY = -imageRect.top + mFocusRect.top;
        } else if (imageRect.bottom < mFocusRect.bottom) {
            deltaY = -imageRect.bottom + mFocusRect.bottom;
        }
        matrix.postTranslate(deltaX, deltaY);
    }

    /**
     * 获取当前图片允许的最大缩放比
     */
    private float maxPostScale() {
        float imageMatrixValues[] = new float[9];
        matrix.getValues(imageMatrixValues);
        float curScale = Math.abs(imageMatrixValues[0]) + Math.abs(imageMatrixValues[1]);
        return mMaxScale / curScale;
    }

    /**
     * 计算两点之间的距离
     */
    private float spacing(float x1, float y1, float x2, float y2) {
        float x = x1 - x2;
        float y = y1 - y2;
        return (float) Math.sqrt(x * x + y * y);
    }

    /**
     * 计算两点之间的距离
     */
    private float spacing(PointF pA, PointF pB) {
        return spacing(pA.x, pA.y, pB.x, pB.y);
    }

    /**
     * 双击触发的方法
     */
    private void doubleClick(float x, float y) {
        float p[] = new float[9];
        matrix.getValues(p);
        float curScale = Math.abs(p[0]) + Math.abs(p[1]);
        float minScale = getScale(mRotatedImageWidth, mRotatedImageHeight, mFocusWidth, mFocusHeight, true);
        if (curScale < mMaxScale) {
            //每次双击的时候，缩放加 minScale
            float toScale = Math.min(curScale + minScale, mMaxScale) / curScale;
            matrix.postScale(toScale, toScale, x, y);
        } else {
            float toScale = minScale / curScale;
            matrix.postScale(toScale, toScale, x, y);
            fixTranslation();
        }
        setImageMatrix(matrix);
    }

    /**
     * @param expectWidth     期望的宽度
     * @param exceptHeight    期望的高度
     * @param isSaveRectangle 是否按矩形区域保存图片
     * @return 裁剪后的Bitmap
     */
    public Bitmap getCropBitmap(int expectWidth, int exceptHeight, boolean isSaveRectangle) {
        if (expectWidth <= 0 || exceptHeight < 0) return null;

        Bitmap srcBitmap = null;
        Drawable drawable = getDrawable();
        if (drawable instanceof BitmapDrawable) {
            srcBitmap = ((BitmapDrawable) drawable).getBitmap();
        }
        if (srcBitmap == null) {
            return null;
        }
        srcBitmap = rotate(srcBitmap, sumRotateLevel * 90);  //最好用level，因为角度可能不是90的整数
        if (srcBitmap == null) {
            return null;
        }
        return makeCropBitmap(srcBitmap, mFocusRect, getImageMatrixRect(), expectWidth, exceptHeight, isSaveRectangle);
    }

    /**
     * @param bitmap  要旋转的图片
     * @param degrees 选择的角度（单位 度）
     * @return 旋转后的Bitmap
     */
    private Bitmap rotate(Bitmap bitmap, int degrees) {
        if (degrees != 0 && bitmap != null) {
            Matrix matrix = new Matrix();
            matrix.setRotate(degrees, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
            try {
                Bitmap rotateBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                if (bitmap != rotateBitmap) {
//                    bitmap.recycle();
                    return rotateBitmap;
                }
            } catch (OutOfMemoryError ex) {
                ex.printStackTrace();
            }
        }
        return bitmap;
    }

    /**
     * @return 获取当前图片显示的矩形区域
     */
    private RectF getImageMatrixRect() {
        RectF rectF = new RectF();
        rectF.set(0, 0, getDrawable().getIntrinsicWidth(), getDrawable().getIntrinsicHeight());
        matrix.mapRect(rectF);
        return rectF;
    }

    /**
     * @param bitmap          需要裁剪的图片
     * @param focusRect       中间需要裁剪的矩形区域
     * @param imageMatrixRect 当前图片在屏幕上的显示矩形区域
     * @param expectWidth     希望获得的图片宽度，如果图片宽度不足时，拉伸图片
     * @param exceptHeight    希望获得的图片高度，如果图片高度不足时，拉伸图片
     * @param isSaveRectangle 是否希望按矩形区域保存图片
     * @return 裁剪后的图片的Bitmap
     */
    private Bitmap makeCropBitmap(Bitmap bitmap, RectF focusRect, RectF imageMatrixRect, int expectWidth, int exceptHeight, boolean isSaveRectangle) {

            float scale = imageMatrixRect.width() / bitmap.getWidth();
            int left = (int) ((focusRect.left - imageMatrixRect.left) / scale);
            int top = (int) ((focusRect.top - imageMatrixRect.top) / scale);
            int width = (int) (focusRect.width() / scale);
            int height = (int) (focusRect.height() / scale);

            if (left < 0) left = 0;
            if (top < 0) top = 0;
            if (left + width > bitmap.getWidth()) width = bitmap.getWidth() - left;
            if (top + height > bitmap.getHeight()) height = bitmap.getHeight() - top;

        try {
            bitmap = Bitmap.createBitmap(bitmap, left, top, width, height);
            if (expectWidth != width || exceptHeight != height) {
                bitmap = Bitmap.createScaledBitmap(bitmap, expectWidth, exceptHeight, true);
                if (mStyle == CropImageView.Style.CIRCLE && !isSaveRectangle) {
                    //如果是圆形，就将图片裁剪成圆的
                    int length = Math.min(expectWidth, exceptHeight);
                    int radius = length / 2;
                    Bitmap circleBitmap = Bitmap.createBitmap(length, length, Bitmap.Config.ARGB_8888);
                    Canvas canvas = new Canvas(circleBitmap);
                    BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
                    Paint paint = new Paint();
                    paint.setShader(bitmapShader);
                    canvas.drawCircle(expectWidth / 2f, exceptHeight / 2f, radius, paint);
                    bitmap = circleBitmap;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    /**
     * @param folder          希望保存的文件夹
     * @param expectWidth     希望保存的图片宽度
     * @param exceptHeight    希望保存的图片高度
     * @param isSaveRectangle 是否希望按矩形区域保存图片
     */
    public void saveBitmapToFile(File folder, int expectWidth, int exceptHeight, boolean isSaveRectangle) {
        if (mSaving) return;
        mSaving = true;
        final Bitmap croppedImage = getCropBitmap(expectWidth, exceptHeight, isSaveRectangle);
        Bitmap.CompressFormat outputFormat = Bitmap.CompressFormat.JPEG;
        File saveFile = createFile(folder, "IMG_", ".jpg");
        if (mStyle == CropImageView.Style.CIRCLE && !isSaveRectangle) {
            outputFormat = Bitmap.CompressFormat.PNG;
            saveFile = createFile(folder, "IMG_", ".png");
        }
        final Bitmap.CompressFormat finalOutputFormat = outputFormat;
        final File finalSaveFile = saveFile;
        new Thread() {
            @Override
            public void run() {
                saveOutput(croppedImage, finalOutputFormat, finalSaveFile);
            }
        }.start();
    }

    /**
     * 根据系统时间、前缀、后缀产生一个文件
     */
    private File createFile(File folder, String prefix, String suffix) {
        if (!folder.exists() || !folder.isDirectory()) folder.mkdirs();
        try {
            File nomedia = new File(folder, ".nomedia");  //在当前文件夹底下创建一个 .nomedia 文件
            if (!nomedia.exists()) nomedia.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA);
        String filename = prefix + dateFormat.format(new Date(System.currentTimeMillis())) + suffix;
        return new File(folder, filename);
    }

    /**
     * 将图片保存在本地
     */
    private void saveOutput(Bitmap croppedImage, Bitmap.CompressFormat outputFormat, File saveFile) {
        OutputStream outputStream = null;
        try {
            outputStream = getContext().getContentResolver().openOutputStream(Uri.fromFile(saveFile));
            if (outputStream != null) croppedImage.compress(outputFormat, 90, outputStream);
            Message.obtain(mHandler, SAVE_SUCCESS, saveFile).sendToTarget();
            croppedImage.recycle();
        } catch (Exception ex) {
            ex.printStackTrace();
            Message.obtain(mHandler, SAVE_ERROR, saveFile).sendToTarget();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        mSaving = false;

    }

    private  class InnerHandler extends Handler {
        public InnerHandler() {
            super(Looper.getMainLooper());
        }

        @Override
        public void handleMessage(Message msg) {
            File saveFile = (File) msg.obj;
            switch (msg.what) {
                case SAVE_SUCCESS:
                    if (mListener != null) mListener.onBitmapSaveSuccess(saveFile);
                    break;
                case SAVE_ERROR:
                    if (mListener != null) mListener.onBitmapSaveError(saveFile);
                    break;
            }
        }
    }

    /**
     * 图片保存完成的监听
     */
    private  OnBitmapSaveCompleteListener mListener;

    public interface OnBitmapSaveCompleteListener {
        void onBitmapSaveSuccess(File file);

        void onBitmapSaveError(File file);
    }

    public void setOnBitmapSaveCompleteListener(OnBitmapSaveCompleteListener listener) {
        mListener = listener;
    }

    /**
     * 返回焦点框宽度
     */
    public int getFocusWidth() {
        return mFocusWidth;
    }

    /**
     * 设置焦点框的宽度
     */
    public void setFocusWidth(int width) {
        mFocusWidth = width;
        initImage();
    }

    /**
     * 获取焦点框的高度
     */
    public int getFocusHeight() {
        return mFocusHeight;
    }

    /**
     * 设置焦点框的高度
     */
    public void setFocusHeight(int height) {
        mFocusHeight = height;
        initImage();
    }

    /**
     * 返回阴影颜色
     */
    public int getMaskColor() {
        return mMaskColor;
    }

    /**
     * 设置阴影颜色
     */
    public void setMaskColor(int color) {
        mMaskColor = color;
        invalidate();
    }

    /**
     * 返回焦点框边框颜色
     */
    public int getFocusColor() {
        return mBorderColor;
    }

    /**
     * 设置焦点框边框颜色
     */
    public void setBorderColor(int color) {
        mBorderColor = color;
        invalidate();
    }

    /**
     * 返回焦点框边框绘制宽度
     */
    public float getBorderWidth() {
        return mBorderWidth;
    }

    /**
     * 设置焦点边框宽度
     */
    public void setBorderWidth(int width) {
        mBorderWidth = width;
        invalidate();
    }

    /**
     * 设置焦点框的形状
     */
    public void setFocusStyle(Style style) {
        this.mStyle = style;
        invalidate();
    }

    /**
     * 获取焦点框的形状
     */
    public Style getFocusStyle() {
        return mStyle;
    }
}
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import devin.com.picturepicker.activity.PictureCropActivity;
import devin.com.picturepicker.activity.PictureGridActivity;
import devin.com.picturepicker.activity.PicturePreviewActivity;
import devin.com.picturepicker.constant.PreviewAction;
import devin.com.picturepicker.javabean.PictureItem;
import devin.com.picturepicker.options.CropOptions;
import devin.com.picturepicker.options.PickOptions;
import devin.com.picturepicker.pick.PicturePicker;
import devin.com.picturepicker.utils.ImageLoader;
import devin.com.picturepicker.utils.PictureLangUtils;
import devin.com.picturepicker.view.CropImageView;
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                PickOptions options = new PickOptions.Builder()
                        //是否仅拍照 默认false
                        .setJustTakePhoto(rgPickType.getCheckedRadioButtonId() == R.id.rb_just_take_photo)
                        //是否可多选 默认true
                        .setMultiMode(rgPickType.getCheckedRadioButtonId() == R.id.rb_multi)
                        //多选时最大选择数量 默认 9
                        .setPickMaxCount(seekBar.getProgress())
                        //选择图片时点击是否可查看大图，默认true（多选模式有效）
                        .setCanPreviewImg(cbCanPreview.isChecked())
                        //选择图片时是否可拍照 默认true
                        .setShowCamera(cbShowCamera.isChecked())
                        //是否显示 gif ，默认true
                        .setSelectGif(cbShowGif.isChecked())
                        .build();

                //默认配置
//        PicturePicker.getInstance().startPickPicture(MainActivity.this, PICK_IMG_REQUEST);
                PicturePicker.getInstance().startPickPicture(MainActivity.this, PICK_IMG_REQUEST, options);
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (pictureItemList.isEmpty()) {
                    Toast.makeText(MainActivity.this, "先选图片", Toast.LENGTH_SHORT).show();
                } else {
                    CropOptions cropOptions = new CropOptions.Builder()
                            .setOutPutX(Integer.parseInt(etOutPutX.getText().toString()))
                            .setOutPutY(Integer.parseInt(etOutPutY.getText().toString()))
                            .setFocusWidth(Integer.parseInt(etFarmWidth.getText().toString()))
                            .setFocusHeight(Integer.parseInt(etFarmHeight.getText().toString()))
                            .setStyle(rbRectangle.isChecked() ? CropImageView.Style.RECTANGLE : CropImageView.Style.CIRCLE)
                            .setSaveRectangle(!cbSaveByFarmShape.isSaveEnabled())
                            .build();

                    PictureCropActivity.startPictureCropActivity(MainActivity.this, pictureItemList.get(0).pictureAbsPath, cropOptions, CROP_IMG_REQUEST);
                }
            }
        });

    }


    @Override
    protected void attachBaseContext(Context newBase) {
        Context context = PictureLangUtils.setLanguage(newBase, MyApplication.locale);
        super.attachBaseContext(context);
    }



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        assignViews();
        initRecyclerView();
    }


    private void initRecyclerView() {

        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
        recyclerView.setLayoutManager(gridLayoutManager);
        sampleAdapter = new SampleAdapter();
        recyclerView.setAdapter(sampleAdapter);
    }


    private class SampleAdapter extends RecyclerView.Adapter<SampleHolder> {

        @Override
        public SampleHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            ImageView imageView = new ImageView(MainActivity.this);
            int w = (parent.getRight() - parent.getLeft()) / 3;
            imageView.setLayoutParams(new LinearLayout.LayoutParams(w, w));
            imageView.setPadding(1, 1, 1, 1);
            return new SampleHolder(imageView);
        }

        @Override
        public int getItemCount() {
            return pictureItemList.size();
        }

        @Override
        public void onBindViewHolder(final SampleHolder holder, int position) {


            ImageLoader.load(getApplication(),pictureItemList.get(position).pictureAbsPath,(ImageView) holder.itemView);

            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    new AlertDialog.Builder(MainActivity.this)
                            .setItems(new CharSequence[]{"仅预览图片", "预览且可删除", "预览且图片可长按"}, new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    switch (i) {
                                        case 0:
                                            PicturePreviewActivity.startActivityWithOnlyPreview(MainActivity.this, pictureItemList, holder.getAdapterPosition());
                                            break;
                                        case 1:
                                            // 如果是 string list，可直接使用 PicturePreviewActivity.startActivityWithPreviewDel() 方法
                                            PicturePreviewActivity.startActivity(MainActivity.this, pictureItemList, holder.getAdapterPosition(), PreviewAction.PREVIEW_DELETE, PREVIEW_IMG_REQUEST);