├── app ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── dimens.xml │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_delete.png │ │ │ ├── ic_add_big.png │ │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ └── layout │ │ │ └── activity_main.xml │ │ ├── java │ │ └── net │ │ │ └── arvin │ │ │ └── selectordemo │ │ │ ├── App.java │ │ │ └── MainActivity.java │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle ├── selectorlibrary ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── ids.xml │ │ │ ├── dimen.xml │ │ │ ├── strings.xml │ │ │ ├── dimens.xml │ │ │ ├── attrs.xml │ │ │ ├── styles.xml │ │ │ └── colors.xml │ │ ├── drawable-xxhdpi │ │ │ ├── ps_icon.png │ │ │ ├── ps_ic_back.png │ │ │ ├── ps_ic_play.png │ │ │ ├── ps_ic_text.png │ │ │ ├── ps_img_msc.png │ │ │ ├── ps_ic_close.png │ │ │ ├── ps_ic_delete.png │ │ │ ├── ps_ic_pencil.png │ │ │ ├── ps_ic_radio.png │ │ │ ├── ps_ic_reset.png │ │ │ ├── ps_ic_resize.png │ │ │ ├── ps_ic_rotate.png │ │ │ ├── ps_img_blur.png │ │ │ ├── ps_edit_ic_back.png │ │ │ ├── ps_ic_rollback.png │ │ │ ├── ps_ic_selected.png │ │ │ ├── ps_ic_tag_gif.png │ │ │ ├── ps_ic_tag_video.png │ │ │ ├── ps_ic_text_bg.png │ │ │ ├── ps_img_blur_bg.png │ │ │ ├── ps_img_msc_bg.png │ │ │ ├── ps_tools_bg.9.png │ │ │ ├── ps_ic_title_arrow.png │ │ │ ├── ps_ic_radio_selected.png │ │ │ └── ps_ic_radio_transparent.png │ │ ├── xml │ │ │ └── ps_file_paths.xml │ │ ├── drawable │ │ │ ├── ps_bg_title.xml │ │ │ ├── ps_thumbnail_select.xml │ │ │ ├── ps_bg_video_tag.xml │ │ │ ├── ps_item_select_bg.xml │ │ │ ├── ps_bg_send.xml │ │ │ └── ps_delete_bg.xml │ │ ├── layout │ │ │ ├── ps_item_media.xml │ │ │ ├── ps_item_preview.xml │ │ │ ├── ps_item_thumbnail.xml │ │ │ ├── ps_item_media_folder.xml │ │ │ ├── ps_layout_media.xml │ │ │ ├── ps_layout_input_text.xml │ │ │ ├── ps_fragment_preview.xml │ │ │ └── ps_activity_selector.xml │ │ ├── color │ │ │ ├── ps_send_color.xml │ │ │ └── ps_bottom_text_color.xml │ │ └── anim │ │ │ ├── ps_fade_in.xml │ │ │ └── ps_fade_out.xml │ │ ├── java │ │ └── net │ │ │ └── arvin │ │ │ └── selector │ │ │ ├── engines │ │ │ ├── ImageEngine.java │ │ │ ├── TextEngine.java │ │ │ └── defaultimpl │ │ │ │ └── DefaultTextEngine.java │ │ │ ├── uis │ │ │ ├── adapters │ │ │ │ ├── OnAdapterItemClickListener.java │ │ │ │ ├── BaseAdapter.java │ │ │ │ ├── PreviewAdapter.java │ │ │ │ ├── FolderAdapter.java │ │ │ │ ├── ThumbnailAdapter.java │ │ │ │ └── MediaAdapter.java │ │ │ ├── widgets │ │ │ │ ├── photoview │ │ │ │ │ ├── OnOutsidePhotoTapListener.java │ │ │ │ │ ├── OnViewDragListener.java │ │ │ │ │ ├── OnScaleChangedListener.java │ │ │ │ │ ├── OnMatrixChangedListener.java │ │ │ │ │ ├── OnViewTapListener.java │ │ │ │ │ ├── OnSingleFlingListener.java │ │ │ │ │ ├── OnPhotoTapListener.java │ │ │ │ │ ├── OnGestureListener.java │ │ │ │ │ ├── Util.java │ │ │ │ │ └── Compat.java │ │ │ │ ├── editable │ │ │ │ │ ├── OnEditTouchListener.java │ │ │ │ │ ├── BaseEditHelper.java │ │ │ │ │ ├── RotateGestureDetector.java │ │ │ │ │ ├── KeyboardHeightUtil.java │ │ │ │ │ ├── ColorView.java │ │ │ │ │ ├── InputTextLayout.java │ │ │ │ │ ├── PaintingHelper.java │ │ │ │ │ ├── SpecialBgEditText.java │ │ │ │ │ ├── PaintColorBarLayout.java │ │ │ │ │ └── CropRotateView.java │ │ │ │ ├── FolderRecyclerView.java │ │ │ │ ├── FolderHelper.java │ │ │ │ ├── MediaView.java │ │ │ │ └── GridDivider.java │ │ │ └── fragments │ │ │ │ └── BaseFragment.java │ │ │ ├── data │ │ │ ├── MediaCallback.java │ │ │ ├── MediaType.java │ │ │ ├── MediaFolder.java │ │ │ ├── MediaStorageStrategy.java │ │ │ ├── SelectorParams.java │ │ │ └── Media.java │ │ │ ├── utils │ │ │ ├── MediaScanner.java │ │ │ ├── TakePhotoUtil.java │ │ │ ├── PSUtil.java │ │ │ ├── UiUtil.java │ │ │ └── AnimUtil.java │ │ │ └── SelectorHelper.java │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── gradle.properties ├── gradlew.bat ├── gradlew └── README.md /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /selectorlibrary/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':selectorlibrary' 2 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/values/dimen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | PictureSelector 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/app/src/main/res/mipmap-xxhdpi/ic_delete.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_add_big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/app/src/main/res/mipmap-xxhdpi/ic_add_big.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_icon.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_back.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_play.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_text.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_img_msc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_img_msc.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_close.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_delete.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_pencil.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_radio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_radio.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_reset.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_resize.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_rotate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_rotate.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_img_blur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_img_blur.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_edit_ic_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_edit_ic_back.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_rollback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_rollback.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_selected.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_tag_gif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_tag_gif.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_tag_video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_tag_video.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_text_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_text_bg.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_img_blur_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_img_blur_bg.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_img_msc_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_img_msc_bg.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_tools_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_tools_bg.9.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_title_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_title_arrow.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | *.zip 4 | /local.properties 5 | /.idea 6 | /.idea/workspace.xml 7 | /.idea/libraries 8 | .DS_Store 9 | /build 10 | /gradle 11 | /captures 12 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_radio_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_radio_selected.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_radio_transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinljw/PictureSelector/HEAD/selectorlibrary/src/main/res/drawable-xxhdpi/ps_ic_radio_transparent.png -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/xml/ps_file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable/ps_bg_title.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Apr 24 13:44:21 CST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip 7 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable/ps_thumbnail_select.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/layout/ps_item_media.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/color/ps_send_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable/ps_bg_video_tag.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/color/ps_bottom_text_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/engines/ImageEngine.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.engines; 2 | 3 | import android.net.Uri; 4 | import android.widget.ImageView; 5 | 6 | /** 7 | * Created by arvinljw on 2020/7/14 16:17 8 | * Function: 9 | * Desc: 10 | */ 11 | public interface ImageEngine { 12 | void loadImage(ImageView imageView, Uri uri); 13 | } 14 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/adapters/OnAdapterItemClickListener.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.uis.adapters; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by arvinljw on 2020/7/31 18:35 7 | * Function: 8 | * Desc: 9 | */ 10 | public interface OnAdapterItemClickListener { 11 | void onAdapterItemClicked(View v, T item, int pos); 12 | } 13 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/data/MediaCallback.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.data; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by arvinljw on 2020/7/16 16:47 7 | * Function: 8 | * Desc: 9 | */ 10 | public interface MediaCallback { 11 | void mediaFolderCallback(List folders); 12 | 13 | void mediasCallback(long bucketId, int page, List medias); 14 | } 15 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/widgets/photoview/OnOutsidePhotoTapListener.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.uis.widgets.photoview; 2 | 3 | import android.widget.ImageView; 4 | 5 | /** 6 | * Callback when the user tapped outside of the photo 7 | */ 8 | public interface OnOutsidePhotoTapListener { 9 | 10 | /** 11 | * The outside of the photo has been tapped 12 | */ 13 | void onOutsidePhotoTap(ImageView imageView); 14 | } 15 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable/ps_item_select_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/anim/ps_fade_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 11 | 14 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/anim/ps_fade_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 11 | 14 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/widgets/editable/OnEditTouchListener.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.uis.widgets.editable; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by arvinljw on 2020/8/9 00:05 7 | * Function: 8 | * Desc: 9 | */ 10 | public abstract class OnEditTouchListener implements View.OnTouchListener { 11 | private boolean intercept; 12 | 13 | public boolean isIntercept() { 14 | return intercept; 15 | } 16 | 17 | public void setIntercept(boolean intercept) { 18 | this.intercept = intercept; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable/ps_bg_send.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/drawable/ps_delete_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/widgets/photoview/OnViewDragListener.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.uis.widgets.photoview; 2 | 3 | /** 4 | * Interface definition for a callback to be invoked when the photo is experiencing a drag event 5 | */ 6 | public interface OnViewDragListener { 7 | 8 | /** 9 | * Callback for when the photo is experiencing a drag event. This cannot be invoked when the 10 | * user is scaling. 11 | * 12 | * @param dx The change of the coordinates in the x-direction 13 | * @param dy The change of the coordinates in the y-direction 14 | */ 15 | void onDrag(float dx, float dy); 16 | } 17 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/widgets/photoview/OnScaleChangedListener.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.uis.widgets.photoview; 2 | 3 | 4 | /** 5 | * Interface definition for callback to be invoked when attached ImageView scale changes 6 | */ 7 | public interface OnScaleChangedListener { 8 | 9 | /** 10 | * Callback for when the scale changes 11 | * 12 | * @param scaleFactor the scale factor (less than 1 for zoom out, greater than 1 for zoom in) 13 | * @param focusX focal point X position 14 | * @param focusY focal point Y position 15 | */ 16 | void onScaleChange(float scaleFactor, float focusX, float focusY); 17 | } 18 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/widgets/photoview/OnMatrixChangedListener.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.uis.widgets.photoview; 2 | 3 | import android.graphics.RectF; 4 | 5 | /** 6 | * Interface definition for a callback to be invoked when the internal Matrix has changed for 7 | * this View. 8 | */ 9 | public interface OnMatrixChangedListener { 10 | 11 | /** 12 | * Callback for when the Matrix displaying the Drawable has changed. This could be because 13 | * the View's bounds have changed, or the user has zoomed. 14 | * 15 | * @param rect - Rectangle displaying the Drawable's new bounds. 16 | */ 17 | void onMatrixChanged(RectF rect); 18 | } 19 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/widgets/photoview/OnViewTapListener.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.uis.widgets.photoview; 2 | 3 | import android.view.View; 4 | 5 | public interface OnViewTapListener { 6 | 7 | /** 8 | * A callback to receive where the user taps on a ImageView. You will receive a callback if 9 | * the user taps anywhere on the view, tapping on 'whitespace' will not be ignored. 10 | * 11 | * @param view - View the user tapped. 12 | * @param x - where the user tapped from the left of the View. 13 | * @param y - where the user tapped from the top of the View. 14 | */ 15 | void onViewTap(View view, float x, float y); 16 | } 17 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/arvin/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /selectorlibrary/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/arvin/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/java/net/arvin/selectordemo/App.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selectordemo; 2 | 3 | import android.app.Application; 4 | import android.net.Uri; 5 | import android.widget.ImageView; 6 | 7 | import com.bumptech.glide.Glide; 8 | 9 | import net.arvin.selector.SelectorHelper; 10 | import net.arvin.selector.engines.ImageEngine; 11 | 12 | public class App extends Application { 13 | @Override 14 | public void onCreate() { 15 | super.onCreate(); 16 | SelectorHelper.init(new ImageEngine() { 17 | @Override 18 | public void loadImage(ImageView imageView, Uri uri) { 19 | Glide.with(imageView) 20 | .load(uri) 21 | .into(imageView); 22 | } 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/layout/ps_item_preview.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/widgets/photoview/OnSingleFlingListener.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.uis.widgets.photoview; 2 | 3 | import android.view.MotionEvent; 4 | 5 | /** 6 | * A callback to be invoked when the ImageView is flung with a single 7 | * touch 8 | */ 9 | public interface OnSingleFlingListener { 10 | 11 | /** 12 | * A callback to receive where the user flings on a ImageView. You will receive a callback if 13 | * the user flings anywhere on the view. 14 | * 15 | * @param e1 MotionEvent the user first touch. 16 | * @param e2 MotionEvent the user last touch. 17 | * @param velocityX distance of user's horizontal fling. 18 | * @param velocityY distance of user's vertical fling. 19 | */ 20 | boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY); 21 | } 22 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/layout/ps_item_thumbnail.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 22 | 23 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/widgets/photoview/OnPhotoTapListener.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.uis.widgets.photoview; 2 | 3 | import android.widget.ImageView; 4 | 5 | /** 6 | * A callback to be invoked when the Photo is tapped with a single 7 | * tap. 8 | */ 9 | public interface OnPhotoTapListener { 10 | 11 | /** 12 | * A callback to receive where the user taps on a photo. You will only receive a callback if 13 | * the user taps on the actual photo, tapping on 'whitespace' will be ignored. 14 | * 15 | * @param view ImageView the user tapped. 16 | * @param x where the user tapped from the of the Drawable, as percentage of the 17 | * Drawable width. 18 | * @param y where the user tapped from the top of the Drawable, as percentage of the 19 | * Drawable height. 20 | */ 21 | void onPhotoTap(ImageView view, float x, float y); 22 | } 23 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | 8 | 9 | 11 | 12 | 13 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 30 5 | 6 | defaultConfig { 7 | applicationId "net.arvin.selectordemo" 8 | minSdkVersion 16 9 | targetSdkVersion 30 10 | versionCode 11 11 | versionName "2.0.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(include: ['*.jar'], dir: 'libs') 23 | implementation 'androidx.appcompat:appcompat:1.4.1' 24 | implementation 'androidx.recyclerview:recyclerview:1.2.1' 25 | implementation 'com.github.bumptech.glide:glide:4.13.2' 26 | // implementation 'com.github.arvinljw:PictureSelector:3.0.0' 27 | implementation project(':selectorlibrary') 28 | implementation 'com.github.arvinljw:PermissionHelper:v2.0.1' 29 | 30 | } 31 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/engines/TextEngine.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.engines; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | 6 | import net.arvin.selector.data.MediaType; 7 | import net.arvin.selector.uis.fragments.PreviewFragment; 8 | 9 | /** 10 | * Created by arvinljw on 2020/7/14 16:17 11 | * Function: 12 | * Desc: 13 | */ 14 | public interface TextEngine { 15 | String titleAll(Context context, MediaType mediaType); 16 | 17 | String titleAllVideo(Context context); 18 | 19 | String ensureChoose(Context context, int count, int maxCount); 20 | 21 | String alreadyMaxCount(Context context, int count); 22 | 23 | String previewTitle(Context context, int count, int maxCount); 24 | 25 | String previewCount(Context context, int count); 26 | 27 | String currentWeek(Context context); 28 | 29 | String currentMonth(Context context); 30 | 31 | String notFoundVideoPlayer(Context context); 32 | 33 | String deleteTips(Context context); 34 | 35 | String releaseDeleteTips(Context context); 36 | } 37 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/data/MediaType.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.data; 2 | 3 | /** 4 | * Created by arvinljw on 2020/7/14 16:31 5 | * Function: 6 | * Desc: 7 | */ 8 | public enum MediaType { 9 | IMAGE(true), IMAGE_NO_GIF(false), VIDEO, ALL; 10 | 11 | /** 12 | * 是否有gif标识,对VIDEO和ALL无效,VIDEO就不会有gif,all是包含有gif 13 | */ 14 | private boolean hasGif; 15 | 16 | MediaType() { 17 | } 18 | 19 | MediaType(boolean hasGif) { 20 | this.hasGif = hasGif; 21 | } 22 | 23 | public boolean hasGif() { 24 | return hasGif; 25 | } 26 | 27 | public static boolean isGif(String mimeType) { 28 | if (mimeType == null) return false; 29 | return mimeType.equals("image/gif"); 30 | } 31 | 32 | public static boolean isImage(String mimeType) { 33 | if (mimeType == null) return false; 34 | return mimeType.startsWith("image"); 35 | } 36 | 37 | public static boolean isVideo(String mimeType) { 38 | if (mimeType == null) return false; 39 | return mimeType.startsWith("video"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/widgets/photoview/OnGestureListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2011, 2012 Chris Banes. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package net.arvin.selector.uis.widgets.photoview; 17 | 18 | interface OnGestureListener { 19 | 20 | /** 21 | * 增加个方向,优化滑动冲突 22 | */ 23 | void onDrag(float dx, float dy, int orientation); 24 | 25 | void onFling(float startX, float startY, float velocityX, 26 | float velocityY); 27 | 28 | void onScale(float scaleFactor, float focusX, float focusY); 29 | 30 | } -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 确定 3 | 确定(%1$d/%2$d) 4 | 图片和视频 5 | 所有视频 6 | 所有图片 7 | 最多选择%1$d个文件 8 | %1$d/%2$d 9 | 选择 10 | 预览 11 | 预览(%1$d) 12 | 原图 13 | 本周 14 | 本月 15 | 没有找到视频播放器 16 | 完成 17 | 编辑 18 | 取消 19 | 拖到此处可删除 20 | 松手即可删除 21 | 确定 22 | 23 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 84dp 4 | 72dp 5 | 68dp 6 | 64dp 7 | 60dp 8 | 56dp 9 | 48dp 10 | 40dp 11 | 36dp 12 | 32dp 13 | 24dp 14 | 20dp 15 | 16dp 16 | 12dp 17 | 8dp 18 | 6dp 19 | 4dp 20 | 2dp 21 | 1dp 22 | 0.5dp 23 | 24 | 28sp 25 | 16sp 26 | 14sp 27 | 12sp 28 | 180dp 29 | 80dp 30 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/adapters/BaseAdapter.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.uis.adapters; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.recyclerview.widget.RecyclerView; 8 | 9 | import net.arvin.selector.data.Media; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * Created by arvinljw on 2020/7/22 17:06 15 | * Function: 16 | * Desc: 17 | */ 18 | public abstract class BaseAdapter extends RecyclerView.Adapter { 19 | protected Context context; 20 | protected List items; 21 | protected OnAdapterItemClickListener onItemClickListener; 22 | 23 | public BaseAdapter(Context context, List items) { 24 | this.context = context; 25 | this.items = items; 26 | } 27 | 28 | public void setOnItemClickListener(OnAdapterItemClickListener onItemClickListener) { 29 | this.onItemClickListener = onItemClickListener; 30 | } 31 | 32 | public List getItems() { 33 | return items; 34 | } 35 | 36 | @Override 37 | public int getItemCount() { 38 | return items.size(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /selectorlibrary/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | 4 | group = 'com.github.arvinljw' 5 | 6 | android { 7 | compileSdkVersion 30 8 | 9 | defaultConfig { 10 | minSdkVersion 16 11 | targetSdkVersion 30 12 | } 13 | // build a jar with source files 14 | task sourcesJar(type: Jar) { 15 | from android.sourceSets.main.java.srcDirs 16 | classifier = 'sources' 17 | } 18 | task javadoc(type: Javadoc) { 19 | failOnError false 20 | source = android.sourceSets.main.java.sourceFiles 21 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 22 | classpath += configurations.compile 23 | } 24 | // build a jar with javadoc 25 | task javadocJar(type: Jar, dependsOn: javadoc) { 26 | classifier = 'javadoc' 27 | from javadoc.destinationDir 28 | } 29 | artifacts { 30 | archives sourcesJar 31 | archives javadocJar 32 | } 33 | } 34 | 35 | dependencies { 36 | implementation fileTree(include: ['*.jar'], dir: 'libs') 37 | compileOnly 'androidx.appcompat:appcompat:1.4.1' 38 | compileOnly 'androidx.recyclerview:recyclerview:1.2.1' 39 | } 40 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /selectorlibrary/src/main/java/net/arvin/selector/uis/fragments/BaseFragment.java: -------------------------------------------------------------------------------- 1 | package net.arvin.selector.uis.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import androidx.annotation.IdRes; 9 | import androidx.annotation.NonNull; 10 | import androidx.annotation.Nullable; 11 | import androidx.fragment.app.Fragment; 12 | 13 | /** 14 | * Created by arvinljw on 2020/7/22 16:20 15 | * Function: 16 | * Desc: 17 | */ 18 | public abstract class BaseFragment extends Fragment { 19 | protected View root; 20 | 21 | @Nullable 22 | @Override 23 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 24 | root = inflater.inflate(getLayoutId(), null); 25 | return root; 26 | } 27 | 28 | @Override 29 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 30 | super.onViewCreated(view, savedInstanceState); 31 | init(); 32 | } 33 | 34 | protected T findViewById(@IdRes int id) { 35 | return root.findViewById(id); 36 | } 37 | 38 | protected abstract int getLayoutId(); 39 | 40 | protected abstract void init(); 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 18 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 |