lmw
2025-04-24 718f31c92e2029d05260810435a2c70cef6e6ce5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
package com.ypx.imagepicker.builder;
 
import android.app.Activity;
import android.os.Bundle;
 
import com.ypx.imagepicker.R;
import com.ypx.imagepicker.activity.multi.MultiImagePickerActivity;
import com.ypx.imagepicker.activity.multi.MultiImagePickerFragment;
import com.ypx.imagepicker.bean.ImageItem;
import com.ypx.imagepicker.bean.MimeType;
import com.ypx.imagepicker.bean.PickerError;
import com.ypx.imagepicker.bean.SelectMode;
import com.ypx.imagepicker.bean.selectconfig.MultiSelectConfig;
import com.ypx.imagepicker.data.OnImagePickCompleteListener;
import com.ypx.imagepicker.helper.PickerErrorExecutor;
import com.ypx.imagepicker.presenter.IPickerPresenter;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
 
import static com.ypx.imagepicker.activity.multi.MultiImagePickerActivity.INTENT_KEY_SELECT_CONFIG;
import static com.ypx.imagepicker.activity.multi.MultiImagePickerActivity.INTENT_KEY_PRESENTER;
 
/**
 * Description: 多选选择器构造类
 * <p>
 * Author: peixing.yang
 * Date: 2018/9/19 16:56
 */
public class MultiPickerBuilder {
    private MultiSelectConfig selectConfig;
    private IPickerPresenter presenter;
 
    public MultiPickerBuilder(IPickerPresenter presenter) {
        this.presenter = presenter;
        this.selectConfig = new MultiSelectConfig();
    }
 
    /**
     * @param isAutoComplete 设置单选模式下是否点击item就自动回调
     */
    public MultiPickerBuilder setSinglePickWithAutoComplete(boolean isAutoComplete) {
        selectConfig.setSinglePickAutoComplete(isAutoComplete);
        return this;
    }
 
    /**
     * @param selectLimit 设置最大数量限制
     */
    public MultiPickerBuilder setMaxCount(int selectLimit) {
        selectConfig.setMaxCount(selectLimit);
        return this;
    }
 
    /**
     * @param selectMode 设置选择模式
     *                   {@link SelectMode}
     */
    public MultiPickerBuilder setSelectMode(int selectMode) {
        selectConfig.setSelectMode(selectMode);
        return this;
    }
 
    /**
     * @param duration 设置视频可选择的最大时长
     */
    public MultiPickerBuilder setMaxVideoDuration(long duration) {
        this.selectConfig.setMaxVideoDuration(duration);
        return this;
    }
 
    /**
     * @param duration 设置视频可选择的最小时长
     */
    public MultiPickerBuilder setMinVideoDuration(long duration) {
        this.selectConfig.setMinVideoDuration(duration);
        return this;
    }
 
    /**
     * 设置文件加载类型
     *
     * @param mimeTypes 文件类型数组
     */
    public MultiPickerBuilder mimeTypes(MimeType... mimeTypes) {
        if (mimeTypes == null || mimeTypes.length == 0) {
            return this;
        }
        Set<MimeType> mimeTypeSet = new HashSet<>(Arrays.asList(mimeTypes));
        return mimeTypes(mimeTypeSet);
    }
 
    /**
     * 设置文件加载类型
     *
     * @param mimeTypes 文件类型集合
     */
    public MultiPickerBuilder filterMimeTypes(Set<MimeType> mimeTypes) {
        if (mimeTypes != null && selectConfig != null && selectConfig.getMimeTypes() != null) {
            selectConfig.getMimeTypes().removeAll(mimeTypes);
        }
        return this;
    }
 
    /**
     * 设置需要过滤掉的文件加载类型
     *
     * @param mimeTypes 需要过滤的文件类型数组
     */
    public MultiPickerBuilder filterMimeTypes(MimeType... mimeTypes) {
        if (mimeTypes == null || mimeTypes.length == 0) {
            return this;
        }
        Set<MimeType> mimeTypeSet = new HashSet<>(Arrays.asList(mimeTypes));
        return filterMimeTypes(mimeTypeSet);
    }
 
    /**
     * 设置需要加载的文件类型
     *
     * @param mimeTypes 需要过滤的文件类型集合
     */
    public MultiPickerBuilder mimeTypes(Set<MimeType> mimeTypes) {
        if (mimeTypes == null || mimeTypes.size() == 0) {
            return this;
        }
        selectConfig.setMimeTypes(mimeTypes);
        return this;
    }
 
    /**
     * @param columnCount 设置列数
     */
    public MultiPickerBuilder setColumnCount(int columnCount) {
        selectConfig.setColumnCount(columnCount);
        return this;
    }
 
    /**
     * @param showCamera 显示拍照item
     */
    public MultiPickerBuilder showCamera(boolean showCamera) {
        selectConfig.setShowCamera(showCamera);
        return this;
    }
 
    /**
     * 只在全部媒体相册里展示拍照
     */
    public MultiPickerBuilder showCameraOnlyInAllMediaSet(boolean showCamera) {
        selectConfig.setShowCameraInAllMedia(showCamera);
        return this;
    }
 
    /**
     * @param isSinglePickImageOrVideoType 是否只能选择视频或图片
     */
    public MultiPickerBuilder setSinglePickImageOrVideoType(boolean isSinglePickImageOrVideoType) {
        selectConfig.setSinglePickImageOrVideoType(isSinglePickImageOrVideoType);
        return this;
    }
 
 
    /**
     * @param isVideoSinglePick 视频是否单选
     */
    public MultiPickerBuilder setVideoSinglePick(boolean isVideoSinglePick) {
        selectConfig.setVideoSinglePick(isVideoSinglePick);
        return this;
    }
 
 
    //—————————————————————— 以下为微信选择器特有的属性 ——————————————————————
 
    /**
     * @param isPreview 视频是否支持预览
     */
    public MultiPickerBuilder setPreviewVideo(boolean isPreview) {
        selectConfig.setCanPreviewVideo(isPreview);
        return this;
    }
 
    /**
     * @param isPreview 是否开启预览
     */
    public MultiPickerBuilder setPreview(boolean isPreview) {
        selectConfig.setPreview(isPreview);
        return this;
    }
 
    /**
     * @param isOriginal 设置是否支持原图选项
     */
    public MultiPickerBuilder setOriginal(boolean isOriginal) {
        selectConfig.setShowOriginalCheckBox(isOriginal);
        return this;
    }
 
    /**
     * @param isOriginal 设置原图选项默认值,true则代表默认打开原图,false代表不打开
     */
    public MultiPickerBuilder setDefaultOriginal(boolean isOriginal) {
        selectConfig.setDefaultOriginal(isOriginal);
        return this;
    }
 
    /**
     * @param imageList 设置屏蔽项,默认打开选择器不可选择屏蔽列表的媒体文件
     * @param <T>       String or ImageItem
     */
    public <T> MultiPickerBuilder setShieldList(ArrayList<T> imageList) {
        if (imageList == null || imageList.size() == 0) {
            return this;
        }
        selectConfig.setShieldImageList(transitArray(imageList));
        return this;
    }
 
    /**
     * @param imageList 设置上一次选择的媒体文件,默认还原上一次选择,可取消
     * @param <T>       String or ImageItem
     */
    public <T> MultiPickerBuilder setLastImageList(ArrayList<T> imageList) {
        if (imageList == null || imageList.size() == 0) {
            return this;
        }
        selectConfig.setLastImageList(transitArray(imageList));
        return this;
    }
 
 
    //—————————————————————— 以下为单图剪裁的属性 ——————————————————————
 
    /**
     * 设置剪裁最小间距,默认充满
     *
     * @param margin 间距
     */
    public MultiPickerBuilder cropRectMinMargin(int margin) {
        selectConfig.setCropRectMargin(margin);
        return this;
    }
 
    /**
     * 设置剪裁模式,
     * <p>
     * MultiSelectConfig.STYLE_FILL:充满模式
     * MultiSelectConfig.STYLE_GAP:留白模式
     *
     * @param style MultiSelectConfig.STYLE_FILL or  MultiSelectConfig.STYLE_GAP
     */
    public MultiPickerBuilder cropStyle(int style) {
        selectConfig.setCropStyle(style);
        return this;
    }
 
    /**
     * 设置留白剪裁模式下背景色,如果设置成透明色,则默认生成png图片
     *
     * @param color 背景色
     */
    public MultiPickerBuilder cropGapBackgroundColor(int color) {
        selectConfig.setCropGapBackgroundColor(color);
        return this;
    }
 
    /**
     * 设置单张图片剪裁比例
     *
     * @param x 剪裁比例x
     * @param y 剪裁比例y
     */
    public MultiPickerBuilder setCropRatio(int x, int y) {
        selectConfig.setCropRatio(x, y);
        return this;
    }
 
    /**
     * 开启圆形剪裁
     */
    public MultiPickerBuilder cropAsCircle() {
        selectConfig.setCircle(true);
        return this;
    }
 
    /**
     * 剪裁完成的图片是否保存在DCIM目录下
     *
     * @param isSaveInDCIM true:存储在系统目录DCIM下 false:存储在 data/包名/files/imagePicker/ 目录下
     */
    public MultiPickerBuilder cropSaveInDCIM(boolean isSaveInDCIM) {
        selectConfig.saveInDCIM(isSaveInDCIM);
        return this;
    }
 
    /**
     * 单图剪裁页面,剪裁框是否在最上层
     *
     * @param singleCropCutNeedTop 剪裁框是否在activity最顶层(会盖住所有的view)
     */
    public MultiPickerBuilder setSingleCropCutNeedTop(boolean singleCropCutNeedTop) {
        selectConfig.setSingleCropCutNeedTop(singleCropCutNeedTop);
        return this;
    }
 
    //—————————————————————— 以上为单图剪裁的属性 ——————————————————————
 
    /**
     * @param config 选择配置
     */
    public MultiPickerBuilder withMultiSelectConfig(MultiSelectConfig config) {
        this.selectConfig = config;
        return this;
    }
 
    /**
     * fragment模式调用
     *
     * @param completeListener 选择回调
     * @return MultiImagePickerFragment
     */
    public MultiImagePickerFragment pickWithFragment(OnImagePickCompleteListener completeListener) {
        checkVideoAndImage();
        MultiImagePickerFragment mFragment = new MultiImagePickerFragment();
        Bundle bundle = new Bundle();
        bundle.putSerializable(INTENT_KEY_SELECT_CONFIG, selectConfig);
        bundle.putSerializable(INTENT_KEY_PRESENTER, presenter);
        mFragment.setArguments(bundle);
        mFragment.setOnImagePickCompleteListener(completeListener);
        return mFragment;
    }
 
    /**
     * 直接开启相册选择
     *
     * @param context  页面调用者
     * @param listener 选择器选择回调
     */
    public void pick(Activity context, final OnImagePickCompleteListener listener) {
        checkVideoAndImage();
        if (selectConfig.getMimeTypes() == null || selectConfig.getMimeTypes().size() == 0) {
            PickerErrorExecutor.executeError(listener, PickerError.MIMETYPES_EMPTY.getCode());
            presenter.tip(context, context.getString(R.string.picker_str_tip_mimeTypes_empty));
            return;
        }
        MultiImagePickerActivity.intent(context, selectConfig, presenter, listener);
    }
 
    /**
     * 调用单图剪裁
     *
     * @param context  页面调用者
     * @param listener 选择器剪裁回调,只支持一张图片
     */
    public void crop(Activity context, OnImagePickCompleteListener listener) {
        setMaxCount(1);
        filterMimeTypes(MimeType.ofVideo());
        setSinglePickImageOrVideoType(false);
        setSinglePickWithAutoComplete(true);
        setVideoSinglePick(false);
        setShieldList(null);
        setLastImageList(null);
        setPreview(false);
        selectConfig.setSelectMode(SelectMode.MODE_CROP);
        if (selectConfig.isCircle()) {
            selectConfig.setCropRatio(1, 1);
        }
        if (selectConfig.getMimeTypes() == null || selectConfig.getMimeTypes().size() == 0) {
            PickerErrorExecutor.executeError(listener, PickerError.MIMETYPES_EMPTY.getCode());
            presenter.tip(context, context.getString(R.string.picker_str_tip_mimeTypes_empty));
            return;
        }
        MultiImagePickerActivity.intent(context, selectConfig, presenter, listener);
    }
 
    /**
     * 检测文件加载类型中是否全是图片或视频
     */
    private void checkVideoAndImage() {
        if (selectConfig == null) {
            return;
        }
        selectConfig.setShowVideo(false);
        selectConfig.setShowImage(false);
        for (MimeType mimeType : selectConfig.getMimeTypes()) {
            if (MimeType.ofVideo().contains(mimeType)) {
                selectConfig.setShowVideo(true);
            }
            if (MimeType.ofImage().contains(mimeType)) {
                selectConfig.setShowImage(true);
            }
        }
    }
 
    /**
     * 数据类型转化
     */
    private <T> ArrayList<ImageItem> transitArray(ArrayList<T> imageList) {
        ArrayList<ImageItem> items = new ArrayList<>();
        for (T t : imageList) {
            if (t instanceof String) {
                ImageItem imageItem = new ImageItem();
                imageItem.path = (String) t;
                items.add(imageItem);
            } else if (t instanceof ImageItem) {
                items.add((ImageItem) t);
            } else {
                throw new RuntimeException("ImageList item must be instanceof String or ImageItem");
            }
        }
        return items;
    }
}