├── simaple ├── .gitignore ├── keystore │ ├── keystore密码 │ └── photo.jks ├── simaple-release.apk ├── src │ └── main │ │ ├── assets │ │ └── test.jpeg │ │ ├── res │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ └── styles.xml │ │ ├── mipmap-xhdpi │ │ │ ├── resx.jpg │ │ │ └── ic_launcher.png │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ │ └── dimens.xml │ │ └── layout │ │ │ ├── activity_kt_custom_page.xml │ │ │ ├── activity_custom_pager.xml │ │ │ └── activity_main.xml │ │ ├── java │ │ └── com │ │ │ └── simaple │ │ │ ├── UserBean.kt │ │ │ ├── App.java │ │ │ ├── MyPhotoBean.java │ │ │ ├── CustomInsetsRelativeLayout.java │ │ │ ├── activity │ │ │ ├── MyPhotoPagerActivity.java │ │ │ └── CustomPhotoPageActivity.kt │ │ │ └── ImageProvider.java │ │ └── AndroidManifest.xml ├── build.gradle └── proguard-rules.pro ├── photoLibrary ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── mipmap-xhdpi │ │ │ ├── gif_icon.png │ │ │ ├── ic_launcher.png │ │ │ ├── select_icon.png │ │ │ ├── take_photo.png │ │ │ ├── video_icon.png │ │ │ ├── failure_image.jpg │ │ │ └── video_play_icon.png │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ ├── values-v21 │ │ │ └── dimens.xml │ │ ├── anim │ │ │ ├── bottom_in.xml │ │ │ ├── bottom_out.xml │ │ │ ├── image_pager_enter_animation.xml │ │ │ └── image_pager_exit_animation.xml │ │ ├── menu │ │ │ ├── menu_ok.xml │ │ │ └── menu_pick.xml │ │ ├── layout │ │ │ ├── activity_clipicture.xml │ │ │ ├── toolbar_layout.xml │ │ │ ├── activity_photo_detail_pager.xml │ │ │ ├── activity_video_play.xml │ │ │ ├── activity_photo_select.xml │ │ │ ├── item_photo_pick.xml │ │ │ ├── item_photo_gallery.xml │ │ │ └── activity_photo_pick.xml │ │ ├── values-w820dp │ │ │ └── dimens.xml │ │ ├── values │ │ │ ├── colors.xml │ │ │ ├── attrs.xml │ │ │ ├── styles.xml │ │ │ ├── strings.xml │ │ │ └── dimens.xml │ │ ├── values-v26 │ │ │ └── styles.xml │ │ ├── values-v27 │ │ │ └── styles.xml │ │ └── values-v29 │ │ │ └── styles.xml │ │ ├── java │ │ └── com │ │ │ └── awen │ │ │ └── photo │ │ │ ├── photopick │ │ │ ├── loader │ │ │ │ ├── MediaType.java │ │ │ │ ├── PhotoDirectoryLoader.java │ │ │ │ ├── VideoCursorLoader.java │ │ │ │ ├── PhotoCursorLoader.java │ │ │ │ └── MediaStoreHelper.java │ │ │ ├── widget │ │ │ │ ├── photodraweeview │ │ │ │ │ ├── OnTouchEventAndScaleChangeListener.java │ │ │ │ │ ├── OnScaleChangeListener.java │ │ │ │ │ ├── OnViewTapListener.java │ │ │ │ │ ├── OnPhotoTapListener.java │ │ │ │ │ ├── OnScaleDragGestureListener.java │ │ │ │ │ ├── IAttacher.java │ │ │ │ │ ├── DefaultOnDoubleTapListener.java │ │ │ │ │ ├── PhotoDraweeView.java │ │ │ │ │ └── ScaleDragDetector.java │ │ │ │ ├── HackyViewPager.java │ │ │ │ ├── clipimage │ │ │ │ │ ├── ClipImageLayout.java │ │ │ │ │ └── ClipImageBorderView.java │ │ │ │ ├── RoundProgressBarDrawable.java │ │ │ │ └── RoundProgressBar.java │ │ │ ├── bean │ │ │ │ ├── PhotoResultBean.java │ │ │ │ ├── PageReferenceBean.java │ │ │ │ ├── PhotoDirectory.java │ │ │ │ ├── PhotoPreviewBean.java │ │ │ │ ├── PhotoPickBean.java │ │ │ │ ├── Photo.java │ │ │ │ └── PhotoPagerBean.java │ │ │ ├── util │ │ │ │ ├── FileSizeUtil.java │ │ │ │ ├── BitmapUtil.java │ │ │ │ ├── ViewUtil.java │ │ │ │ ├── AppPathUtil.java │ │ │ │ └── PermissionUtil.java │ │ │ ├── ui │ │ │ │ ├── VideoPlayActivity.java │ │ │ │ ├── VideoPlayLayout.java │ │ │ │ └── ClipPictureActivity.java │ │ │ ├── controller │ │ │ │ └── PhotoPreviewConfig.java │ │ │ ├── adapter │ │ │ │ └── PhotoGalleryAdapter.java │ │ │ └── data │ │ │ │ └── Data.java │ │ │ ├── controller │ │ │ └── ToolBarHelper.java │ │ │ ├── FrescoBaseActivity.java │ │ │ ├── Awen.java │ │ │ └── FrescoImageLoader.java │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── v1.096-README.md ├── pictrue ├── WechatIMG20.jpeg ├── WechatIMG21.jpeg ├── 304079-052c8fd0c9d22efd.gif ├── 304079-8d726553c6c0b6ba.gif ├── 304079-e4c819f695ed83c0.gif └── device-2017-10-25-033458.png ├── .idea ├── caches │ ├── gradle_models.ser │ └── build_file_checksums.ser ├── encodings.xml ├── vcs.xml ├── runConfigurations.xml ├── modules.xml ├── gradle.xml ├── jarRepositories.xml ├── misc.xml └── codeStyles │ └── Project.xml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── gradle.properties ├── gradlew.bat └── gradlew /simaple/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /photoLibrary/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':photoLibrary', ':simaple' 2 | -------------------------------------------------------------------------------- /simaple/keystore/keystore密码: -------------------------------------------------------------------------------- 1 | keystore密码:123456 2 | alias:photo 3 | password:123456 -------------------------------------------------------------------------------- /v1.096-README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/v1.096-README.md -------------------------------------------------------------------------------- /pictrue/WechatIMG20.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/pictrue/WechatIMG20.jpeg -------------------------------------------------------------------------------- /pictrue/WechatIMG21.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/pictrue/WechatIMG21.jpeg -------------------------------------------------------------------------------- /simaple/keystore/photo.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/simaple/keystore/photo.jks -------------------------------------------------------------------------------- /simaple/simaple-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/simaple/simaple-release.apk -------------------------------------------------------------------------------- /.idea/caches/gradle_models.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/.idea/caches/gradle_models.ser -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /pictrue/304079-052c8fd0c9d22efd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/pictrue/304079-052c8fd0c9d22efd.gif -------------------------------------------------------------------------------- /pictrue/304079-8d726553c6c0b6ba.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/pictrue/304079-8d726553c6c0b6ba.gif -------------------------------------------------------------------------------- /pictrue/304079-e4c819f695ed83c0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/pictrue/304079-e4c819f695ed83c0.gif -------------------------------------------------------------------------------- /simaple/src/main/assets/test.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/simaple/src/main/assets/test.jpeg -------------------------------------------------------------------------------- /.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /pictrue/device-2017-10-25-033458.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/pictrue/device-2017-10-25-033458.png -------------------------------------------------------------------------------- /simaple/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | PhotoPick-Simaple 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /simaple/src/main/res/mipmap-xhdpi/resx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/simaple/src/main/res/mipmap-xhdpi/resx.jpg -------------------------------------------------------------------------------- /simaple/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/simaple/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /simaple/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/simaple/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /simaple/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/simaple/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /simaple/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/simaple/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /photoLibrary/src/main/res/mipmap-xhdpi/gif_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/photoLibrary/src/main/res/mipmap-xhdpi/gif_icon.png -------------------------------------------------------------------------------- /simaple/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/simaple/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/photoLibrary/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /photoLibrary/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/photoLibrary/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /photoLibrary/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/photoLibrary/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /photoLibrary/src/main/res/mipmap-xhdpi/select_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/photoLibrary/src/main/res/mipmap-xhdpi/select_icon.png -------------------------------------------------------------------------------- /photoLibrary/src/main/res/mipmap-xhdpi/take_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/photoLibrary/src/main/res/mipmap-xhdpi/take_photo.png -------------------------------------------------------------------------------- /photoLibrary/src/main/res/mipmap-xhdpi/video_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/photoLibrary/src/main/res/mipmap-xhdpi/video_icon.png -------------------------------------------------------------------------------- /photoLibrary/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/photoLibrary/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /photoLibrary/src/main/res/mipmap-xhdpi/failure_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/photoLibrary/src/main/res/mipmap-xhdpi/failure_image.jpg -------------------------------------------------------------------------------- /photoLibrary/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/photoLibrary/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /photoLibrary/src/main/res/mipmap-xhdpi/video_play_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awent/PhotoPick-Master/HEAD/photoLibrary/src/main/res/mipmap-xhdpi/video_play_icon.png -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/values-v21/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 25dp 4 | 71dp 5 | -------------------------------------------------------------------------------- /simaple/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /simaple/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/loader/MediaType.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.loader; 2 | 3 | public interface MediaType { 4 | 5 | int ALL = 0;//默认,包括图片和视频 6 | 7 | int ONLY_IMAGE = 1;//只有图片 8 | 9 | int ONLY_VIDEO = 2;//只有视频 10 | } 11 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/anim/bottom_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/anim/bottom_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Jul 01 17:17:18 CST 2020 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 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/menu/menu_ok.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /simaple/src/main/java/com/simaple/UserBean.kt: -------------------------------------------------------------------------------- 1 | package com.simaple 2 | 3 | class UserBean { 4 | var code = 0 5 | var msg: String? = null 6 | var list: List? = null 7 | 8 | class User { 9 | var avatar: String? = null 10 | var smallAvatar: String? = null 11 | var name: String? = null 12 | var age = 0 13 | } 14 | } -------------------------------------------------------------------------------- /photoLibrary/src/main/res/layout/activity_clipicture.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /simaple/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/menu/menu_pick.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 14 | 15 | -------------------------------------------------------------------------------- /simaple/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | #80000000 8 | #00000000 9 | #D9D9D9 10 | #80ffffff 11 | #00000000 12 | 13 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/anim/image_pager_enter_animation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 17 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/anim/image_pager_exit_animation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 17 | 18 | -------------------------------------------------------------------------------- /simaple/src/main/java/com/simaple/App.java: -------------------------------------------------------------------------------- 1 | package com.simaple; 2 | 3 | import android.app.Application; 4 | 5 | import com.awen.photo.FrescoImageLoader; 6 | 7 | /** 8 | * Created by Awen 9 | */ 10 | 11 | public class App extends Application { 12 | 13 | @Override 14 | public void onCreate() { 15 | super.onCreate(); 16 | FrescoImageLoader.init(this); 17 | //下面是配置toolbar颜色和存储图片地址的 18 | // FrescoImageLoader.init(this,android.R.color.black); 19 | // FrescoImageLoader.init(this,android.R.color.holo_blue_light,"/storage/xxxx/xxx"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/widget/photodraweeview/OnTouchEventAndScaleChangeListener.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.widget.photodraweeview; 2 | 3 | import android.graphics.Matrix; 4 | import android.view.MotionEvent; 5 | 6 | /** 7 | * 解决多指缩放和下拉冲突的,该接口主要用于用于ScalePhotoView,因为PhotoDraweeView它的多指操作,原图缩小的时候,onTouch会被我这里中断 8 | * Created by Awen 9 | */ 10 | 11 | public interface OnTouchEventAndScaleChangeListener { 12 | 13 | void onPhotoTouchEvent(MotionEvent ev); 14 | 15 | void onPhotoScaleChange(float matrixScale); 16 | 17 | void onPhotoScaleEnd(float matrixScale); 18 | } 19 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/values-v26/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/values-v27/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/widget/photodraweeview/OnScaleChangeListener.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.widget.photodraweeview; 2 | 3 | /** 4 | * Interface definition for callback to be invoked when attached ImageView scale changes 5 | * 6 | * @author Marek Sebera 7 | */ 8 | public interface OnScaleChangeListener { 9 | /** 10 | * Callback for when the scale changes 11 | * 12 | * @param scaleFactor the scale factor (<1 for zoom out, >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 | -------------------------------------------------------------------------------- /simaple/src/main/res/layout/activity_kt_custom_page.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/values-v29/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/layout/toolbar_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/bean/PhotoResultBean.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.bean; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * 从图库选择了或裁剪了的图片 7 | * Created by Awen 8 | */ 9 | 10 | public class PhotoResultBean { 11 | private boolean isOriginalPicture;//用户选择的是否是原图 12 | private ArrayList photoLists; 13 | 14 | public boolean isOriginalPicture() { 15 | return isOriginalPicture; 16 | } 17 | 18 | public void setOriginalPicture(boolean originalPicture) { 19 | isOriginalPicture = originalPicture; 20 | } 21 | 22 | public ArrayList getPhotoLists() { 23 | return photoLists; 24 | } 25 | 26 | public void setPhotoLists(ArrayList photoLists) { 27 | this.photoLists = photoLists; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/widget/photodraweeview/OnViewTapListener.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.widget.photodraweeview; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Interface definition for a callback to be invoked when the ImageView is tapped with a single 7 | * tap. 8 | * 9 | * @author Chris Banes 10 | */ 11 | public interface OnViewTapListener { 12 | /** 13 | * A callback to receive where the user taps on a ImageView. You will receive a callback if 14 | * the user taps anywhere on the view, tapping on 'whitespace' will not be ignored. 15 | * 16 | * @param view - View the user tapped. 17 | * @param x - where the user tapped from the left of the View. 18 | * @param y - where the user tapped from the top of the View. 19 | */ 20 | void onViewTap(View view, float x, float y); 21 | } -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /photoLibrary/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 E:\android\android-studio\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 | 19 | 20 | # Explicitly preserve all serialization members. The Serializable interface 21 | # is only a marker interface, so it wouldn't save them. 22 | 23 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/widget/photodraweeview/OnPhotoTapListener.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.widget.photodraweeview; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Interface definition for a callback to be invoked when the Photo is tapped with a single 7 | * tap. 8 | * 9 | * @author Chris Banes 10 | */ 11 | public interface OnPhotoTapListener { 12 | 13 | /** 14 | * A callback to receive where the user taps on a photo. You will only receive a callback if 15 | * the user taps on the actual photo, tapping on 'whitespace' will be ignored. 16 | * 17 | * @param view - View the user tapped. 18 | * @param x - where the user tapped from the of the Drawable, as percentage of the 19 | * Drawable width. 20 | * @param y - where the user tapped from the top of the Drawable, as percentage of the 21 | * Drawable height. 22 | */ 23 | void onPhotoTap(View view, float x, float y); 24 | } 25 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/bean/PageReferenceBean.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.bean; 2 | 3 | import com.awen.photo.photopick.widget.photodraweeview.PhotoDraweeView; 4 | import com.facebook.imagepipeline.request.ImageRequest; 5 | 6 | public class PageReferenceBean { 7 | 8 | private ImageRequest request; 9 | private PhotoDraweeView photoDraweeView; 10 | 11 | public PageReferenceBean(ImageRequest request, PhotoDraweeView photoDraweeView) { 12 | this.request = request; 13 | this.photoDraweeView = photoDraweeView; 14 | } 15 | 16 | public ImageRequest getRequest() { 17 | return request; 18 | } 19 | 20 | public void setRequest(ImageRequest request) { 21 | this.request = request; 22 | } 23 | 24 | public PhotoDraweeView getPhotoDraweeView() { 25 | return photoDraweeView; 26 | } 27 | 28 | public void setPhotoDraweeView(PhotoDraweeView photoDraweeView) { 29 | this.photoDraweeView = photoDraweeView; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/util/FileSizeUtil.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.util; 2 | 3 | import java.text.DecimalFormat; 4 | 5 | /** 6 | * Created by Awen 7 | */ 8 | 9 | public class FileSizeUtil { 10 | 11 | private static DecimalFormat df = new DecimalFormat("#.00"); 12 | /** 13 | * 转换文件大小 14 | */ 15 | public static String formatFileSize(long fileS) { 16 | if (fileS == 0) { 17 | return "0B"; 18 | } 19 | String fileSizeString; 20 | if (fileS < 1024) { 21 | fileSizeString = df.format((double) fileS) + "B"; 22 | } else if (fileS < 1048576) { 23 | fileSizeString = df.format((double) fileS / 1024) + "KB"; 24 | } else if (fileS < 1073741824) { 25 | fileSizeString = df.format((double) fileS / 1048576) + "MB"; 26 | } else { 27 | fileSizeString = df.format((double) fileS / 1073741824) + "GB"; 28 | } 29 | return fileSizeString; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | systemProp.http.proxyHost=mirrors.opencas.cn 20 | systemProp.http.proxyPort=80 21 | android.useAndroidX=true 22 | android.enableJetifier=true -------------------------------------------------------------------------------- /photoLibrary/src/main/res/layout/activity_photo_detail_pager.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 17 | 18 | 19 | 25 | 26 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/layout/activity_video_play.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 23 | 24 | -------------------------------------------------------------------------------- /simaple/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'kotlin-kapt' 5 | 6 | android { 7 | compileSdkVersion rootProject.ext.android.compileSdkVersion 8 | buildToolsVersion rootProject.ext.android.buildToolsVersion 9 | 10 | defaultConfig { 11 | applicationId "com.simaple" 12 | minSdkVersion 16 13 | targetSdkVersion rootProject.ext.android.targetSdkVersion 14 | versionCode 1 15 | versionName "1.0" 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | implementation fileTree(dir: 'libs', include: ['*.jar']) 27 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 28 | implementation project(':photoLibrary') 29 | implementation "androidx.appcompat:appcompat:1.2.0" 30 | debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4' 31 | //android6.0权限工具类 32 | implementation 'com.lovedise:permissiongen:0.1.1' 33 | } 34 | -------------------------------------------------------------------------------- /simaple/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 24 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/widget/photodraweeview/OnScaleDragGestureListener.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.widget.photodraweeview; 2 | 3 | /** 4 | * **************************************************************************** 5 | * Copyright 2011, 2012 Chris Banes. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * ***************************************************************************** 19 | */ 20 | 21 | public interface OnScaleDragGestureListener { 22 | void onDrag(float dx, float dy); 23 | 24 | void onFling(float startX, float startY, float velocityX, float velocityY); 25 | 26 | void onScale(float scaleFactor, float focusX, float focusY); 27 | 28 | void onScaleEnd(); 29 | } 30 | -------------------------------------------------------------------------------- /simaple/src/main/java/com/simaple/MyPhotoBean.java: -------------------------------------------------------------------------------- 1 | package com.simaple; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | /** 7 | * Created by Awen 8 | */ 9 | 10 | public class MyPhotoBean implements Parcelable { 11 | 12 | private int id; 13 | private String content; 14 | 15 | public MyPhotoBean(){} 16 | 17 | protected MyPhotoBean(Parcel in) { 18 | id = in.readInt(); 19 | content = in.readString(); 20 | } 21 | 22 | public int getId() { 23 | return id; 24 | } 25 | 26 | public void setId(int id) { 27 | this.id = id; 28 | } 29 | 30 | public String getContent() { 31 | return content; 32 | } 33 | 34 | public void setContent(String content) { 35 | this.content = content; 36 | } 37 | 38 | @Override 39 | public int describeContents() { 40 | return 0; 41 | } 42 | 43 | @Override 44 | public void writeToParcel(Parcel dest, int flags) { 45 | dest.writeInt(id); 46 | dest.writeString(content); 47 | } 48 | 49 | public static final Creator CREATOR = new Creator() { 50 | @Override 51 | public MyPhotoBean createFromParcel(Parcel in) { 52 | return new MyPhotoBean(in); 53 | } 54 | 55 | @Override 56 | public MyPhotoBean[] newArray(int size) { 57 | return new MyPhotoBean[size]; 58 | } 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | 34 | 35 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/widget/HackyViewPager.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.widget; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.util.Log; 6 | import android.view.MotionEvent; 7 | 8 | import androidx.viewpager.widget.ViewPager; 9 | 10 | /** 11 | * Hacky fix for Issue #4 and 12 | * http://code.google.com/p/android/issues/detail?id=18990 13 | *

14 | * ScaleGestureDetector seems to mess up the touch events, which means that 15 | * ViewGroups which make use of onInterceptTouchEvent throw a lot of 16 | * IllegalArgumentException: pointerIndex out of range. 17 | *

18 | * There's not much I can do in my code for now, but we can mask the result by 19 | * just catching the problem and ignoring it. 20 | */ 21 | public class HackyViewPager extends ViewPager { 22 | 23 | private static final String TAG = "HackyViewPager"; 24 | 25 | public HackyViewPager(Context context) { 26 | super(context); 27 | } 28 | 29 | public HackyViewPager(Context context, AttributeSet attrs) { 30 | super(context, attrs); 31 | } 32 | 33 | @Override 34 | public boolean onInterceptTouchEvent(MotionEvent ev) { 35 | try { 36 | return super.onInterceptTouchEvent(ev); 37 | } catch (IllegalArgumentException e) { 38 | // 不理会 39 | Log.e(TAG, "hacky viewpager error1"); 40 | return false; 41 | } catch (ArrayIndexOutOfBoundsException e) { 42 | // 不理会 43 | Log.e(TAG, "hacky viewpager error2"); 44 | return false; 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /photoLibrary/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | group='com.github.Awent' 4 | 5 | android { 6 | compileSdkVersion rootProject.ext.android.compileSdkVersion 7 | buildToolsVersion rootProject.ext.android.buildToolsVersion 8 | 9 | defaultConfig { 10 | minSdkVersion 16 11 | targetSdkVersion rootProject.ext.android.targetSdkVersion 12 | versionCode 33 13 | versionName "3.3" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | implementation fileTree(dir: 'libs', include: ['*.jar']) 25 | implementation "androidx.appcompat:appcompat:1.2.0" 26 | implementation "androidx.recyclerview:recyclerview:1.1.0" 27 | implementation "com.facebook.fresco:fresco:2.3.0" 28 | // 支持 GIF 动图,需要添加 29 | implementation "com.facebook.fresco:animated-gif:2.3.0" 30 | // 支持 WebP (静态图+动图),需要添加 31 | implementation "com.facebook.fresco:animated-webp:2.3.0" 32 | implementation "com.facebook.fresco:webpsupport:2.3.0" 33 | //跟随viewpager的点 34 | implementation 'me.relex:circleindicator:1.1.8@aar' 35 | //上滑控制面板,项目中的potopick中有使用案例 36 | implementation 'com.sothree.slidinguppanel:library:3.3.0' 37 | //android6.0权限工具类 38 | implementation 'com.lovedise:permissiongen:0.1.1' 39 | //加载超长图必备库 40 | implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0' 41 | implementation "androidx.legacy:legacy-support-v4:1.0.0" 42 | } 43 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/ui/VideoPlayActivity.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.ui; 2 | 3 | import android.net.Uri; 4 | import android.os.Bundle; 5 | import android.text.TextUtils; 6 | import android.util.Log; 7 | import android.widget.MediaController; 8 | import android.widget.Toast; 9 | import android.widget.VideoView; 10 | 11 | import androidx.annotation.Nullable; 12 | 13 | import com.awen.photo.FrescoBaseActivity; 14 | import com.awen.photo.R; 15 | 16 | /** 17 | * 使用videoView进行视频的简单播放,通过intent接收“videoUrl”, 18 | * 单独显示一个本地视频或网络视频都可以通过intent传递进来 19 | */ 20 | public class VideoPlayActivity extends FrescoBaseActivity { 21 | 22 | @Override 23 | protected void onCreate(@Nullable Bundle arg0) { 24 | setOpenToolBar(false); 25 | super.onCreate(arg0); 26 | String videoUrl = getIntent().getStringExtra("videoUrl"); 27 | if (TextUtils.isEmpty(videoUrl)) { 28 | Log.e("VideoPlayActivity", "videoUrl must not null"); 29 | finish(); 30 | return; 31 | } 32 | setContentView(R.layout.activity_video_play); 33 | toolbar = findViewById(R.id.toolbar); 34 | toolbar.setTitle(""); 35 | setSupportActionBar(toolbar); 36 | VideoView videoView = findViewById(R.id.videoView); 37 | videoView.setVideoURI(Uri.parse(videoUrl)); 38 | MediaController mediaController = new MediaController(this); 39 | videoView.setMediaController(mediaController); 40 | mediaController.setMediaPlayer(videoView); 41 | videoView.requestFocus(); 42 | videoView.start(); 43 | } 44 | 45 | @Override 46 | public void finish() { 47 | super.finish(); 48 | overridePendingTransition(0, R.anim.image_pager_exit_animation); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /simaple/src/main/java/com/simaple/CustomInsetsRelativeLayout.java: -------------------------------------------------------------------------------- 1 | package com.simaple; 2 | 3 | import android.content.Context; 4 | import android.graphics.Rect; 5 | import android.os.Build; 6 | import android.util.AttributeSet; 7 | import android.widget.RelativeLayout; 8 | 9 | /** 10 | * 解决activity设置了状态栏透明,又设置了android:windowSoftInputMode="adjustResize"的时候输入框被输入法挡住的情况
11 | * 这个作为layout的根布局(root),并设置android:fitsSystemWindows="true" 12 | * Created by Awen 13 | */ 14 | public class CustomInsetsRelativeLayout extends RelativeLayout { 15 | private int[] mInsets = new int[4]; 16 | 17 | public CustomInsetsRelativeLayout(Context context) { 18 | super(context); 19 | } 20 | 21 | public CustomInsetsRelativeLayout(Context context, AttributeSet attrs) { 22 | super(context, attrs); 23 | } 24 | 25 | public CustomInsetsRelativeLayout(Context context, AttributeSet attrs, int defStyle) { 26 | super(context, attrs, defStyle); 27 | } 28 | 29 | public final int[] getInsets() { 30 | return mInsets; 31 | } 32 | 33 | @Override 34 | protected final boolean fitSystemWindows(Rect insets) { 35 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 36 | // Intentionally do not modify the bottom inset. For some reason, 37 | // if the bottom inset is modified, window resizing stops working. 38 | // TODO: Figure out why. 39 | 40 | mInsets[0] = insets.left; 41 | mInsets[1] = insets.top; 42 | mInsets[2] = insets.right; 43 | 44 | insets.left = 0; 45 | insets.top = 0; 46 | insets.right = 0; 47 | } 48 | 49 | return super.fitSystemWindows(insets); 50 | } 51 | } -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/util/BitmapUtil.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.util; 2 | 3 | import android.graphics.BitmapFactory; 4 | import android.util.Log; 5 | 6 | import com.awen.photo.photopick.bean.Photo; 7 | 8 | /** 9 | * Created by Awen 10 | */ 11 | public class BitmapUtil { 12 | /** 13 | * 检查文件是否损坏 14 | * Check if the file is corrupted 15 | * 16 | * @return false为不损坏,true为损坏 17 | */ 18 | public static boolean checkImgCorrupted(String filePath) { 19 | BitmapFactory.Options options = new BitmapFactory.Options(); 20 | options.inJustDecodeBounds = true; 21 | BitmapFactory.decodeFile(filePath, options); 22 | return (options.mCancel || options.outWidth == -1 || options.outHeight == -1); 23 | } 24 | 25 | /** 26 | * 检查文件是否损坏,并且给photo添加上长宽 27 | * Check if the file is corrupted 28 | * 29 | * @return false为不损坏,true为损坏 30 | */ 31 | @Deprecated 32 | public static boolean checkImgCorrupted(Photo photo, String filePath) { 33 | BitmapFactory.Options options = new BitmapFactory.Options(); 34 | options.inJustDecodeBounds = true; 35 | BitmapFactory.decodeFile(filePath, options); 36 | 37 | if(options.mCancel || options.outWidth == -1 || options.outHeight == -1){ 38 | return true; 39 | }else { 40 | photo.setWidth(options.outWidth); 41 | photo.setHeight(options.outHeight); 42 | return false; 43 | } 44 | } 45 | 46 | public static int[] getImageSize(String filePath) { 47 | BitmapFactory.Options options = new BitmapFactory.Options(); 48 | options.inJustDecodeBounds = true; 49 | BitmapFactory.decodeFile(filePath, options); 50 | return new int[]{options.outWidth,options.outHeight}; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/widget/clipimage/ClipImageLayout.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.widget.clipimage; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.util.AttributeSet; 6 | import android.util.TypedValue; 7 | import android.widget.RelativeLayout; 8 | 9 | /** 10 | * 裁剪头像整个layout 11 | * 12 | * @author Homk-M 13 | * 14 | */ 15 | public class ClipImageLayout extends RelativeLayout { 16 | 17 | private ClipZoomImageView mZoomImageView; 18 | 19 | /** 20 | * 可以提取为自定义属性 21 | */ 22 | private int mHorizontalPadding = 20; 23 | 24 | public ClipImageLayout(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | 27 | } 28 | 29 | public void init(Context context, Bitmap bitmap) { 30 | mZoomImageView = new ClipZoomImageView(context); 31 | ClipImageBorderView mClipImageView = new ClipImageBorderView(context); 32 | 33 | android.view.ViewGroup.LayoutParams lp = new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, 34 | android.view.ViewGroup.LayoutParams.MATCH_PARENT); 35 | 36 | mZoomImageView.setImageBitmap(bitmap); 37 | 38 | this.addView(mZoomImageView, lp); 39 | this.addView(mClipImageView, lp); 40 | 41 | // 计算padding的px 42 | mHorizontalPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mHorizontalPadding, getResources() 43 | .getDisplayMetrics()); 44 | mZoomImageView.setHorizontalPadding(mHorizontalPadding); 45 | mClipImageView.setHorizontalPadding(mHorizontalPadding); 46 | } 47 | 48 | /** 49 | * 对外公布设置边距的方法,单位为dp 50 | * 51 | * @param mHorizontalPadding 52 | */ 53 | public void setHorizontalPadding(int mHorizontalPadding) { 54 | this.mHorizontalPadding = mHorizontalPadding; 55 | } 56 | 57 | /** 58 | * 裁切图片 59 | * 60 | * @return 61 | */ 62 | public Bitmap clip() { 63 | return mZoomImageView.clip(); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /simaple/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/Awen/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 | #保持 Parcelable 不被混淆 19 | -keep class * implements android.os.Parcelable { 20 | public static final android.os.Parcelable$Creator *; 21 | } 22 | # app javabean classes 23 | -keep class com.awen.photo.photopick.bean.** { *; } 24 | 25 | ##---------------6.0权限 start---------------------------------- 26 | -keepattributes Annotation 27 | -keepclassmembers class ** { 28 | @kr.co.namee.permissiongen.PermissionSuccess public *; 29 | @kr.co.namee.permissiongen.PermissionFail public *; 30 | } 31 | ##---------------6.0权限 end---------------------------------- 32 | 33 | ##---------------fresco start---------------------------------- 34 | # Keep our interfaces so they can be used by other ProGuard rules. 35 | # See http://sourceforge.net/p/proguard/bugs/466/ 36 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip 37 | 38 | # Do not strip any method/class that is annotated with @DoNotStrip 39 | -keep @com.facebook.common.internal.DoNotStrip class * 40 | -keepclassmembers class * { 41 | @com.facebook.common.internal.DoNotStrip *; 42 | } 43 | 44 | # Keep native methods 45 | -keepclassmembers class * { 46 | native ; 47 | } 48 | ##---------------fresco end---------------------------------- 49 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/controller/ToolBarHelper.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.controller; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.LinearLayout; 8 | import androidx.appcompat.widget.Toolbar; 9 | import com.awen.photo.R; 10 | 11 | /** 12 | * Created by Awen 13 | */ 14 | public class ToolBarHelper { 15 | 16 | /*base view*/ 17 | private LinearLayout mContentView; 18 | 19 | /*toolbar*/ 20 | private Toolbar mToolBar; 21 | 22 | public ToolBarHelper(Context context, int layoutId) { 23 | init(context,R.layout.toolbar_layout,layoutId); 24 | } 25 | 26 | public ToolBarHelper(Context context, int toolBarId, int layoutId) { 27 | init(context,toolBarId,layoutId); 28 | } 29 | 30 | private void init(Context context,int toolBarId, int layoutId){ 31 | LayoutInflater mInflater = LayoutInflater.from(context); 32 | /*初始化整个内容-直接创建一个帧布局,作为视图容器的父容器*/ 33 | mContentView = new LinearLayout(context); 34 | ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 35 | ViewGroup.LayoutParams.MATCH_PARENT); 36 | mContentView.setOrientation(LinearLayout.VERTICAL); 37 | mContentView.setLayoutParams(params); 38 | 39 | /*初始化toolbar-通过inflater获取toolbar的布局文件*/ 40 | View toolbar = mInflater.inflate(toolBarId, mContentView); 41 | mToolBar = (Toolbar) toolbar.findViewById(R.id.toolbar); 42 | 43 | /**初始化用户定义的布局*/ 44 | View mUserView = mInflater.inflate(layoutId, null); 45 | mContentView.addView(mUserView,new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); 46 | } 47 | 48 | public LinearLayout getContentView() { 49 | return mContentView; 50 | } 51 | 52 | public Toolbar getToolBar() { 53 | return mToolBar; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | PhotoPickLibrary 3 | 4 | %s张 5 | %s个 6 | SD卡不存在,无法使用此功能 7 | 所有图片 8 | 所有视频 9 | 图片和视频 10 | 图片 11 | 视频 12 | 裁剪 13 | 确定 14 | 预览 15 | 保存图片 16 | 保存失败 17 | 已保存->图库查看,图片地址: \n %s 18 | 相册 19 | 加载中… 20 | 找不到图片 21 | 找不到视频 22 | 取消 23 | 选择 24 | 发送 25 | 发送(%s/%s) 26 | 原图(%s) 27 | 视频(%s) 28 | 29 | 30 | 缺少(相机)权限,无法使用该功能,点击"设置"去开启此权限\n您可在“设置”>“应用”>“权限”中配置权限 31 | 缺少(麦克风)权限,无法使用该功能,点击"设置"去开启此权限\n您可在“设置”>“应用”>“权限”中配置权限 32 | 缺少(麦克风或相机)权限,无法使用该功能,点击"设置"去开启此权限\n您可在“设置”>“应用”>“权限”中配置权限 33 | 缺少(读取位置信息)权限,无法使用该功能,点击"设置"去开启此权限\n您可在“设置”>“应用”>“权限”中配置权限 34 | 本App需要使用(存储)和(读取本机识别码)权限,您是否同意?点击"设置"去开启此权限\n您可在“设置”>“应用”>“权限”中配置权限 35 | 本App需要使用(存储)权限,您是否同意?点击"设置"去开启此权限\n您可在“设置”>“应用”>“权限”中配置权限 36 | 设置 37 | 38 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/loader/PhotoDirectoryLoader.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.loader; 2 | 3 | import android.content.Context; 4 | import android.net.Uri; 5 | import android.provider.MediaStore.Images.Media; 6 | 7 | import androidx.loader.content.CursorLoader; 8 | 9 | import static android.provider.MediaStore.MediaColumns.MIME_TYPE; 10 | 11 | /** 12 | * Created by Awen 13 | */ 14 | public class PhotoDirectoryLoader extends CursorLoader { 15 | 16 | private final static String IMAGE_JPEG = "image/jpeg"; 17 | private final static String IMAGE_PNG = "image/png"; 18 | private final static String IMAGE_GIF = "image/gif"; 19 | private final static String IMAGE_WEBP = "image/webP"; 20 | 21 | final String[] IMAGE_PROJECTION = { 22 | Media._ID, 23 | Media.DATA, 24 | Media.BUCKET_ID, 25 | Media.BUCKET_DISPLAY_NAME, 26 | Media.DATE_ADDED, 27 | Media.SIZE 28 | }; 29 | 30 | public PhotoDirectoryLoader(Context context){ 31 | this(context,false); 32 | } 33 | 34 | public PhotoDirectoryLoader(Context context, boolean showGif) { 35 | super(context); 36 | 37 | setProjection(IMAGE_PROJECTION); 38 | setUri(Media.EXTERNAL_CONTENT_URI); 39 | setSortOrder(Media.DATE_ADDED + " DESC"); 40 | 41 | setSelection( 42 | MIME_TYPE + "=? or " + MIME_TYPE + "=? " + (showGif ? ("or " + MIME_TYPE + "=?") : "")); 43 | String[] selectionArgs; 44 | if (showGif) { 45 | selectionArgs = new String[]{IMAGE_JPEG, IMAGE_PNG, IMAGE_WEBP,IMAGE_GIF}; 46 | } else { 47 | selectionArgs = new String[]{IMAGE_JPEG, IMAGE_PNG,IMAGE_WEBP}; 48 | } 49 | setSelectionArgs(selectionArgs); 50 | } 51 | 52 | 53 | private PhotoDirectoryLoader(Context context, Uri uri, String[] projection, String selection, 54 | String[] selectionArgs, String sortOrder) { 55 | super(context, uri, projection, selection, selectionArgs, sortOrder); 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/util/ViewUtil.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.util; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Point; 6 | import android.os.Build; 7 | import android.util.DisplayMetrics; 8 | import android.view.Display; 9 | import android.view.KeyCharacterMap; 10 | import android.view.KeyEvent; 11 | import android.view.ViewConfiguration; 12 | 13 | /** 14 | * Created by Awen 15 | */ 16 | 17 | public class ViewUtil { 18 | 19 | public static boolean isNavigationBarShow(Activity activity){ 20 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 21 | Display display = activity.getWindowManager().getDefaultDisplay(); 22 | Point size = new Point(); 23 | Point realSize = new Point(); 24 | display.getSize(size); 25 | display.getRealSize(realSize); 26 | return realSize.y!=size.y; 27 | }else { 28 | boolean menu = ViewConfiguration.get(activity).hasPermanentMenuKey(); 29 | boolean back = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); 30 | return menu || back; 31 | } 32 | } 33 | 34 | public static int getNavigationBarHeight(Activity activity) { 35 | if (!isNavigationBarShow(activity)){ 36 | return 0; 37 | } 38 | return activity.getResources().getDimensionPixelSize(activity.getResources().getIdentifier("navigation_bar_height","dimen", "android")); 39 | } 40 | 41 | 42 | public static int getSceenHeight(Activity activity) { 43 | return activity.getWindowManager().getDefaultDisplay().getHeight()+getNavigationBarHeight(activity); 44 | } 45 | 46 | public static int getDisplayHeight(Context context){ 47 | return context.getResources().getDisplayMetrics().heightPixels; 48 | } 49 | 50 | public static int[] getDisplayWidthAndHeight(Context context){ 51 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); 52 | return new int[]{displayMetrics.widthPixels,displayMetrics.heightPixels}; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/ui/VideoPlayLayout.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.ui; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.util.AttributeSet; 6 | import android.view.Gravity; 7 | import android.view.View; 8 | import android.widget.FrameLayout; 9 | import android.widget.ImageView; 10 | import androidx.annotation.NonNull; 11 | import androidx.annotation.Nullable; 12 | 13 | import com.awen.photo.FrescoImageLoader; 14 | import com.awen.photo.R; 15 | 16 | public class VideoPlayLayout extends FrameLayout { 17 | 18 | private Context context; 19 | private String videoPath; 20 | 21 | public VideoPlayLayout(@NonNull Context context) { 22 | super(context); 23 | init(context); 24 | } 25 | 26 | public VideoPlayLayout(@NonNull Context context, @Nullable AttributeSet attrs) { 27 | super(context, attrs); 28 | init(context); 29 | } 30 | 31 | public VideoPlayLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 32 | super(context, attrs, defStyleAttr); 33 | init(context); 34 | } 35 | 36 | private void init(Context context) { 37 | this.context = context; 38 | } 39 | 40 | private void addPlayButton() { 41 | ImageView imageView = new ImageView(context); 42 | imageView.setImageResource(R.mipmap.video_play_icon); 43 | imageView.setScaleType(ImageView.ScaleType.FIT_XY); 44 | LayoutParams params = new LayoutParams(200, 200); 45 | params.gravity = Gravity.CENTER; 46 | imageView.setLayoutParams(params); 47 | addView(imageView); 48 | imageView.setOnClickListener(new OnClickListener() { 49 | @Override 50 | public void onClick(View v) { 51 | FrescoImageLoader.startVideoActivity((Activity) context,videoPath); 52 | } 53 | }); 54 | } 55 | 56 | public void setData(View photoDraweeView, String videoPath) { 57 | this.videoPath = videoPath; 58 | addView(photoDraweeView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 59 | addPlayButton(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/util/AppPathUtil.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.util; 2 | 3 | import android.os.Environment; 4 | import android.text.TextUtils; 5 | 6 | import com.awen.photo.Awen; 7 | import com.awen.photo.R; 8 | 9 | import java.io.File; 10 | 11 | /** 12 | * Created by Awen 13 | */ 14 | public class AppPathUtil { 15 | 16 | /** 17 | * 裁剪头像 18 | * 19 | * @return 20 | */ 21 | public static String getClipPhotoPath() { 22 | return getPath("clip"); 23 | } 24 | 25 | /** 26 | * 保存大图到本地的路径地址 27 | * 28 | * @return String 29 | */ 30 | public static String getBigBitmapCachePath() { 31 | return getPath("Photo"); 32 | } 33 | 34 | private static String getPath(String str) { 35 | String path = null; 36 | if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 37 | path = Environment.getExternalStorageDirectory().getPath(); 38 | } 39 | if (TextUtils.isEmpty(path)) { 40 | path = Awen.getContext().getCacheDir().getPath(); 41 | } 42 | //地址如下:path/appname/appname_photo/ 43 | String app_root_name = Awen.getContext().getString(R.string.app_root_name); 44 | path = path + File.separator + app_root_name + File.separator + app_root_name + "_" + str + File.separator; 45 | exitesFolder(path); 46 | return path; 47 | } 48 | 49 | /** 50 | * 判断文件夹是否存在,不存在则创建 51 | * 52 | * @param path 53 | */ 54 | public static void exitesFolder(String path) { 55 | File file = new File(path); 56 | if (!file.exists()) { 57 | file.mkdirs(); 58 | } 59 | } 60 | 61 | public static String getFileName(String url) { 62 | String fileName = url.substring(url.lastIndexOf("/") + 1, url.length()); 63 | if (!fileName.endsWith(".jpg") && !fileName.endsWith(".png") && !fileName.endsWith(".jpeg") && !fileName.endsWith(".gif") && !fileName.endsWith(".webp")) { 64 | //防止有些图片没有后缀名 65 | fileName = fileName + ".jpg"; 66 | } 67 | return fileName; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/layout/activity_photo_select.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 21 | 22 | 28 | 29 | 38 | 39 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/bean/PhotoDirectory.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.bean; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by Awen 10 | */ 11 | public class PhotoDirectory { 12 | 13 | private String id; 14 | private String coverPath; 15 | private String name; 16 | private long dateAdded; 17 | private List photos = new ArrayList<>(); 18 | private boolean isVideo; 19 | 20 | @Override 21 | public boolean equals(Object o) { 22 | if (this == o) return true; 23 | if (!(o instanceof PhotoDirectory)) return false; 24 | 25 | PhotoDirectory directory = (PhotoDirectory) o; 26 | if(TextUtils.isEmpty(id)) return false; 27 | if (!id.equals(directory.id)) return false; 28 | return name.equals(directory.name); 29 | } 30 | 31 | @Override 32 | public int hashCode() { 33 | int result = id.hashCode(); 34 | result = 31 * result + name.hashCode(); 35 | return result; 36 | } 37 | 38 | public String getId() { 39 | return id; 40 | } 41 | 42 | public void setId(String id) { 43 | this.id = id; 44 | } 45 | 46 | public String getCoverPath() { 47 | return coverPath; 48 | } 49 | 50 | public void setCoverPath(String coverPath) { 51 | this.coverPath = coverPath; 52 | } 53 | 54 | public String getName() { 55 | return name; 56 | } 57 | 58 | public void setName(String name) { 59 | this.name = name; 60 | } 61 | 62 | public long getDateAdded() { 63 | return dateAdded; 64 | } 65 | 66 | public void setDateAdded(long dateAdded) { 67 | this.dateAdded = dateAdded; 68 | } 69 | 70 | public List getPhotos() { 71 | return photos; 72 | } 73 | 74 | public void setPhotos(List photos) { 75 | this.photos = photos; 76 | } 77 | 78 | public void addPhoto(Photo photo) { 79 | photos.add(photo); 80 | } 81 | 82 | public boolean isVideo() { 83 | return isVideo; 84 | } 85 | 86 | public void setVideo(boolean video) { 87 | isVideo = video; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/bean/PhotoPreviewBean.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.bean; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | import java.util.ArrayList; 6 | 7 | /** 8 | * Created by Awen 9 | */ 10 | 11 | public class PhotoPreviewBean implements Parcelable { 12 | 13 | private int position; 14 | private int maxPickSize; 15 | private boolean originalPicture;//是否选择的是原图 16 | private boolean isPreview;//是否是预览 17 | 18 | public PhotoPreviewBean(){} 19 | 20 | 21 | private PhotoPreviewBean(Parcel in) { 22 | position = in.readInt(); 23 | maxPickSize = in.readInt(); 24 | originalPicture = in.readByte() != 0; 25 | isPreview = in.readByte() != 0; 26 | } 27 | 28 | @Override 29 | public void writeToParcel(Parcel dest, int flags) { 30 | dest.writeInt(position); 31 | dest.writeInt(maxPickSize); 32 | dest.writeByte((byte) (originalPicture ? 1 : 0)); 33 | dest.writeByte((byte) (isPreview ? 1 : 0)); 34 | } 35 | 36 | public static final Creator CREATOR = new Creator() { 37 | @Override 38 | public PhotoPreviewBean createFromParcel(Parcel in) { 39 | return new PhotoPreviewBean(in); 40 | } 41 | 42 | @Override 43 | public PhotoPreviewBean[] newArray(int size) { 44 | return new PhotoPreviewBean[size]; 45 | } 46 | }; 47 | 48 | @Override 49 | public int describeContents() { 50 | return 0; 51 | } 52 | 53 | public int getPosition() { 54 | return position; 55 | } 56 | 57 | public void setPosition(int position) { 58 | this.position = position; 59 | } 60 | 61 | public int getMaxPickSize() { 62 | return maxPickSize; 63 | } 64 | 65 | public void setMaxPickSize(int maxPickSize) { 66 | this.maxPickSize = maxPickSize; 67 | } 68 | 69 | public boolean isOriginalPicture() { 70 | return originalPicture; 71 | } 72 | 73 | public void setOriginalPicture(boolean originalPicture) { 74 | this.originalPicture = originalPicture; 75 | } 76 | 77 | public boolean isPreview() { 78 | return isPreview; 79 | } 80 | 81 | public void setPreview(boolean preview) { 82 | isPreview = preview; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/layout/item_photo_pick.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | 24 | 25 | 30 | 31 | 37 | 38 | 46 | 47 | 48 | 55 | 56 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/layout/item_photo_gallery.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 22 | 23 | 31 | 32 | 37 | 38 | 44 | 45 | 46 | 54 | -------------------------------------------------------------------------------- /photoLibrary/src/main/java/com/awen/photo/photopick/widget/photodraweeview/IAttacher.java: -------------------------------------------------------------------------------- 1 | package com.awen.photo.photopick.widget.photodraweeview; 2 | 3 | import android.view.GestureDetector; 4 | import android.view.View; 5 | 6 | /** 7 | * **************************************************************************** 8 | * Copyright 2011, 2012 Chris Banes. 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); 11 | * you may not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | * ***************************************************************************** 22 | */ 23 | 24 | public interface IAttacher { 25 | 26 | public static final float DEFAULT_MAX_SCALE = 3.0f; 27 | public static final float DEFAULT_MID_SCALE = 1.75f; 28 | public static final float DEFAULT_MIN_SCALE = 1.0f; 29 | public static final long ZOOM_DURATION = 200L; 30 | 31 | float getMinimumScale(); 32 | 33 | float getMediumScale(); 34 | 35 | float getMaximumScale(); 36 | 37 | void setMaximumScale(float maximumScale); 38 | 39 | void setMediumScale(float mediumScale); 40 | 41 | void setMinimumScale(float minimumScale); 42 | 43 | float getScale(); 44 | 45 | void setScale(float scale); 46 | 47 | void setScale(float scale, boolean animate); 48 | 49 | void setScale(float scale, float focalX, float focalY, boolean animate); 50 | 51 | void setZoomTransitionDuration(long duration); 52 | 53 | void setAllowParentInterceptOnEdge(boolean allow); 54 | 55 | void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener listener); 56 | 57 | void setOnScaleChangeListener(OnScaleChangeListener listener); 58 | 59 | void setOnLongClickListener(View.OnLongClickListener listener); 60 | 61 | void setOnPhotoTapListener(OnPhotoTapListener listener); 62 | 63 | void setOnViewTapListener(OnViewTapListener listener); 64 | 65 | OnPhotoTapListener getOnPhotoTapListener(); 66 | 67 | OnViewTapListener getOnViewTapListener(); 68 | 69 | void update(int imageInfoWidth, int imageInfoHeight); 70 | } 71 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/layout/activity_photo_pick.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 20 | 21 | 26 | 27 | 28 | 29 | 30 | 38 | 39 | 44 | 45 | 55 | 56 | 60 | 61 | -------------------------------------------------------------------------------- /photoLibrary/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | 0dp 7 | 48dp 8 | 9 | 4dp 10 | 2dp 11 | 5dp 12 | 8dp 13 | 16dp 14 | 22dp 15 | 24dp 16 | 28dp 17 | 32dp 18 | 64dp 19 | 70dp 20 | 1dp 21 | 2dp 22 | 4dp 23 | 6dp 24 | 8dp 25 | 12dp 26 | 16dp 27 | 22dp 28 | 24dp 29 | 28dp 30 | 32dp 31 | 64dp 32 | 33 | 34 | 10sp 35 | 12sp 36 | 14sp 37 | 15sp 38 | 16sp 39 | 18sp 40 | 22sp 41 | 26sp 42 | 40sp 43 | 6sp 44 | 45 | 40dp 46 | 16dp 47 | 20dp 48 | 24dp 49 | 32dp 50 | 40dp 51 | 48dp 52 | 56dp 53 | 54 | 55 | -------------------------------------------------------------------------------- /simaple/src/main/res/layout/activity_custom_pager.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 20 | 21 | 27 | 28 | 37 | 38 | 39 | 45 | 46 |