├── .gitignore ├── .idea ├── assetWizardSettings.xml ├── caches │ ├── build_file_checksums.ser │ └── gradle_models.ser ├── checkstyle-idea.xml ├── codeStyles │ └── Project.xml ├── dbnavigator.xml ├── encodings.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── markdown-navigator.xml ├── markdown-navigator │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── release │ ├── app-release.apk │ └── output.json └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── sxu │ │ └── imageset │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── default_grid_image.jpg │ │ ├── default_list_image.jpg │ │ ├── default_preview_image.jpg │ │ ├── wx_grid_image.jpg │ │ ├── wx_list_image.jpg │ │ └── wx_preview_image.jpg │ ├── java │ │ └── com │ │ │ └── sxu │ │ │ └── imageset │ │ │ ├── AlbumActivity.java │ │ │ ├── ChooseAndCropImageActivity.java │ │ │ ├── ImageLoaderActivity.java │ │ │ ├── MainActivity.java │ │ │ └── WxChoosePhotoActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable-xxhdpi │ │ ├── arrow_icon.png │ │ ├── grid_item_selected_icon.png │ │ ├── grid_item_unselected_icon.png │ │ ├── list_item_selected_icon.png │ │ └── list_item_unselected_icon.png │ │ ├── drawable │ │ ├── default_placeholder_image.xml │ │ ├── grid_checkbox_bg.xml │ │ ├── ic_launcher_background.xml │ │ ├── list_checkbox_bg.xml │ │ └── right_bottom_arrow_icon.xml │ │ ├── layout │ │ ├── activity_album_layout.xml │ │ ├── activity_choose_and_crop_image_layout.xml │ │ ├── activity_image_loader_layout.xml │ │ ├── activity_main.xml │ │ ├── activity_wx_choose_photo_layout.xml │ │ ├── wx_item_photo_grid_layout.xml │ │ └── wx_item_photo_list_layout.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── sxu │ └── imageset │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── imageset ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── sxu │ │ └── smartpicture │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── sxu │ │ │ └── smartpicture │ │ │ ├── album │ │ │ ├── ChoosePhotoPresenter.java │ │ │ ├── CommonAdapter.java │ │ │ ├── FragmentHandlerManager.java │ │ │ ├── PhotoDirectoryBean.java │ │ │ ├── PhotoManager.java │ │ │ ├── PhotoPicker.java │ │ │ ├── activity │ │ │ │ ├── ChoosePhotoActivity.java │ │ │ │ └── PhotoPreviewActivity.java │ │ │ ├── fragment │ │ │ │ ├── PhotoGridFragment.java │ │ │ │ ├── PhotoListFragment.java │ │ │ │ └── PhotoPreviewFragment.java │ │ │ └── listener │ │ │ │ ├── OnItemPhotoCheckedListener.java │ │ │ │ ├── OnPhotoListItemClickListener.java │ │ │ │ ├── OnSelectPhotoListener.java │ │ │ │ └── OnViewCreatedListener.java │ │ │ ├── choosepicture │ │ │ ├── ChoosePhotoDialog.java │ │ │ ├── ChoosePhotoManager.java │ │ │ ├── OnChoosePhotoListener.java │ │ │ └── OnSimpleChoosePhotoListener.java │ │ │ ├── imageloader │ │ │ ├── ImageLoaderManager.java │ │ │ ├── WrapImageView.java │ │ │ ├── instance │ │ │ │ ├── FrescoInstance.java │ │ │ │ ├── GlideInstance.java │ │ │ │ ├── ImageLoaderInstance.java │ │ │ │ └── UILInstance.java │ │ │ ├── listener │ │ │ │ ├── ImageLoaderListener.java │ │ │ │ └── SimpleImageLoaderListener.java │ │ │ ├── transform │ │ │ │ ├── GlideBlurTransform.java │ │ │ │ ├── GlideCircleBitmapTransform.java │ │ │ │ └── GlideRoundBitmapTransform.java │ │ │ └── utils │ │ │ │ ├── DiskLruCache.java │ │ │ │ ├── DiskLruCacheManager.java │ │ │ │ ├── FastBlurUtil.java │ │ │ │ ├── StrictLineReader.java │ │ │ │ └── Util.java │ │ │ ├── manager │ │ │ └── ThreadPoolManager.java │ │ │ ├── utils │ │ │ ├── DisplayUtil.java │ │ │ └── UploadUtils.java │ │ │ └── zoomimage │ │ │ ├── FrescoAttacher.java │ │ │ └── ZoomImageView.java │ └── res │ │ ├── drawable-xxhdpi │ │ ├── ic_launcher.png │ │ ├── photo_selected_icon.png │ │ ├── photo_unselected_icon.png │ │ └── return_icon.png │ │ ├── drawable │ │ ├── common_line_e4.xml │ │ ├── default_placeholder_image.xml │ │ └── place_checkbox_bg.xml │ │ ├── layout │ │ ├── activity_choose_photo_layout.xml │ │ ├── activity_photo_preview_layout.xml │ │ ├── dialog_common_choose_layout.xml │ │ ├── fragment_photo_grid_layout.xml │ │ ├── fragment_photo_list_layout.xml │ │ ├── fragment_photo_preview_layout.xml │ │ ├── fragment_test_layout.xml │ │ ├── item_photo_grid_layout.xml │ │ └── item_photo_list_layout.xml │ │ ├── values-v21 │ │ └── styles.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── sxu │ └── smartpicture │ └── ExampleUnitTest.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/assetWizardSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /.idea/caches/gradle_models.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/.idea/caches/gradle_models.ser -------------------------------------------------------------------------------- /.idea/checkstyle-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 26 | 27 | 28 | 29 | 35 | 36 | 37 | 38 | 39 | 45 | 46 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 36 | -------------------------------------------------------------------------------- /.idea/markdown-navigator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 36 | 37 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /.idea/markdown-navigator/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Android > Lint > Correctness 47 | 48 | 49 | Android > Lint > Performance 50 | 51 | 52 | 53 | 54 | Android 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 66 | 67 | 68 | 69 | 70 | 1.8 71 | 72 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Freeman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 该图片库包含的功能 2 | - 图片加载库的二次封装(一行代码替换图片加载库); 3 | - 相册功能(类似朋友圈选择图片) 4 | - 从相册/相机选择照片并裁剪 5 | - 图片压缩;(使用Luban压缩) 6 | - 上传图片到服务器; 7 | - 上传图片到七牛; 8 | 9 | 详细介绍参考:[Wiki](https://github.com/JuHonggang/ImageSet/wiki) 10 | 11 | ### 添加依赖 12 | 13 | 在项目的build.gradle中添加: 14 | 15 | allprojects { 16 | repositories { 17 | ... 18 | maven { url 'https://jitpack.io' } 19 | } 20 | } 21 | 22 | 在APP模块下的build.gradle中添加依赖: 23 | 24 | dependencies { 25 | implementation 'com.github.JuHonggang:ImageSet:v0.12' 26 | } 27 | 28 | ### License 29 | 30 | Copyright (c) 2018 Freeman 31 | 32 | Permission is hereby granted, free of charge, to any person obtaining a copy 33 | of this software and associated documentation files (the "Software"), to deal 34 | in the Software without restriction, including without limitation the rights 35 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 36 | copies of the Software, and to permit persons to whom the Software is 37 | furnished to do so, subject to the following conditions: 38 | 39 | The above copyright notice and this permission notice shall be included in all 40 | copies or substantial portions of the Software. 41 | 42 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 43 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 44 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 45 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 46 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 47 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 48 | SOFTWARE. 49 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'android-aspectjx' 3 | 4 | android { 5 | compileSdkVersion 26 6 | defaultConfig { 7 | applicationId "com.sxu.imageset" 8 | minSdkVersion 16 9 | targetSdkVersion 26 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | implementation fileTree(dir: 'libs', include: ['*.jar']) 24 | implementation 'com.android.support:appcompat-v7:27.1.1' 25 | implementation 'com.android.support.constraint:constraint-layout:1.0.2' 26 | testImplementation 'junit:junit:4.12' 27 | androidTestImplementation 'com.android.support.test:runner:1.0.1' 28 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' 29 | 30 | implementation project(':imageset') 31 | //implementation 'com.github.JuHonggang:PermissionManager:0.16' 32 | } 33 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/release/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/release/app-release.apk -------------------------------------------------------------------------------- /app/release/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] -------------------------------------------------------------------------------- /app/src/androidTest/java/com/sxu/imageset/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.sxu.imageset; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.sxu.imageset", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 24 | 26 | 28 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/assets/default_grid_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/src/main/assets/default_grid_image.jpg -------------------------------------------------------------------------------- /app/src/main/assets/default_list_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/src/main/assets/default_list_image.jpg -------------------------------------------------------------------------------- /app/src/main/assets/default_preview_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/src/main/assets/default_preview_image.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wx_grid_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/src/main/assets/wx_grid_image.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wx_list_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/src/main/assets/wx_list_image.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wx_preview_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/src/main/assets/wx_preview_image.jpg -------------------------------------------------------------------------------- /app/src/main/java/com/sxu/imageset/AlbumActivity.java: -------------------------------------------------------------------------------- 1 | package com.sxu.imageset; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.BaseAdapter; 11 | import android.widget.Button; 12 | import android.widget.GridView; 13 | import android.widget.ImageView; 14 | 15 | import com.sxu.smartpicture.album.listener.OnSelectPhotoListener; 16 | import com.sxu.smartpicture.album.PhotoPicker; 17 | import com.sxu.smartpicture.imageloader.ImageLoaderManager; 18 | import com.sxu.smartpicture.imageloader.WrapImageView; 19 | import com.sxu.smartpicture.imageloader.instance.FrescoInstance; 20 | import com.sxu.smartpicture.imageloader.instance.GlideInstance; 21 | import com.sxu.smartpicture.imageloader.instance.UILInstance; 22 | import com.sxu.smartpicture.utils.DisplayUtil; 23 | 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | 27 | /** 28 | * @author Freeman 29 | * @date 2017/12/21 30 | */ 31 | 32 | 33 | public class AlbumActivity extends AppCompatActivity { 34 | 35 | private GridView photoGrid; 36 | private BaseAdapter photoAdapter; 37 | private ArrayList selectedPhotos = new ArrayList<>(); 38 | 39 | @Override 40 | protected void onCreate(@Nullable Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_album_layout); 43 | Button chooseButton = (Button)findViewById(R.id.choose_button); 44 | Button chooseWxButton = (Button)findViewById(R.id.choose_wx_button); 45 | photoGrid = (GridView) findViewById(R.id.photo_grid); 46 | 47 | int type = getIntent().getIntExtra("type", 0); 48 | if (!ImageLoaderManager.getInstance().isInit()) { 49 | if (type == 0) { 50 | ImageLoaderManager.getInstance().init(getApplicationContext(), new FrescoInstance()); 51 | } else if (type == 1) { 52 | ImageLoaderManager.getInstance().init(getApplicationContext(), new UILInstance()); 53 | } else if (type == 2) { 54 | ImageLoaderManager.getInstance().init(getApplicationContext(), new GlideInstance()); 55 | } else { 56 | /** 57 | * Nothing 58 | */ 59 | } 60 | } 61 | 62 | chooseButton.setOnClickListener(new View.OnClickListener() { 63 | @Override 64 | public void onClick(View v) { 65 | openDefaultPhotoPicker(); 66 | } 67 | }); 68 | 69 | chooseWxButton.setOnClickListener(new View.OnClickListener() { 70 | @Override 71 | public void onClick(View v) { 72 | openWxPhotoPicker(); 73 | } 74 | }); 75 | } 76 | 77 | /** 78 | * 使用默认的图片选择组件 79 | */ 80 | private void openDefaultPhotoPicker() { 81 | PhotoPicker picker = new PhotoPicker.Builder() 82 | .setIsDialog(false) 83 | .setIsShowCamera(false) 84 | .setMaxPhotoCount(9) 85 | .setSelectedPhotos(selectedPhotos) 86 | .builder(); 87 | picker.chooseImage(AlbumActivity.this, new OnSelectPhotoListener() { 88 | @Override 89 | public void onSelected(ArrayList selectedPhotoList) { 90 | selectedPhotos.clear(); 91 | selectedPhotos.addAll(selectedPhotoList); 92 | setPhotoAdapter(); 93 | } 94 | }); 95 | } 96 | 97 | /** 98 | * 使用仿微信的图片选择组件 注意这种方式需要在onActivityResult获取选择结果 99 | */ 100 | private void openWxPhotoPicker() { 101 | PhotoPicker picker = new PhotoPicker.Builder() 102 | .setIsDialog(false) 103 | .setIsShowCamera(false) 104 | .setMaxPhotoCount(9) 105 | .setSelectedPhotos(selectedPhotos) 106 | .builder(); 107 | picker.chooseImage(AlbumActivity.this, WxChoosePhotoActivity.class); 108 | } 109 | 110 | public static void enter(Context context, int imageLoaderType) { 111 | Intent intent = new Intent(context, AlbumActivity.class); 112 | intent.putExtra("type", imageLoaderType); 113 | context.startActivity(intent); 114 | } 115 | 116 | private void setPhotoAdapter() { 117 | if (photoAdapter == null) { 118 | final int itemSize = (DisplayUtil.getScreenWidth() - DisplayUtil.dpToPx(72)) / 3; 119 | final ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemSize); 120 | photoAdapter = new BaseAdapter() { 121 | @Override 122 | public int getCount() { 123 | return selectedPhotos.size(); 124 | } 125 | 126 | @Override 127 | public Object getItem(int position) { 128 | return selectedPhotos.get(position); 129 | } 130 | 131 | @Override 132 | public long getItemId(int position) { 133 | return position; 134 | } 135 | 136 | @Override 137 | public View getView(int position, View convertView, ViewGroup parent) { 138 | WrapImageView imageView = new WrapImageView(AlbumActivity.this); 139 | imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 140 | ImageLoaderManager.getInstance().displayImage("file://" + getItem(position), imageView, itemSize, itemSize); 141 | imageView.setLayoutParams(params); 142 | return imageView; 143 | } 144 | }; 145 | 146 | photoGrid.setAdapter(photoAdapter); 147 | } else { 148 | photoAdapter.notifyDataSetChanged(); 149 | } 150 | } 151 | 152 | @Override 153 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 154 | super.onActivityResult(requestCode, resultCode, data); 155 | if (requestCode != PhotoPicker.REQUEST_CODE_CHOOSE_PHOTO || data == null) { 156 | return; 157 | } 158 | 159 | List photoList = data.getStringArrayListExtra(PhotoPicker.SELECTED_PHOTOS); 160 | if (photoList != null && photoList.size() > 0) { 161 | selectedPhotos.clear(); 162 | selectedPhotos.addAll(photoList); 163 | setPhotoAdapter(); 164 | } 165 | } 166 | 167 | @Override 168 | protected void onDestroy() { 169 | super.onDestroy(); 170 | ImageLoaderManager.getInstance().onDestroy(); 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /app/src/main/java/com/sxu/imageset/ChooseAndCropImageActivity.java: -------------------------------------------------------------------------------- 1 | package com.sxu.imageset; 2 | 3 | import android.content.Intent; 4 | import android.net.Uri; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.text.TextUtils; 9 | import android.view.View; 10 | import android.widget.AdapterView; 11 | import android.widget.Button; 12 | import android.widget.ImageView; 13 | import android.widget.Toast; 14 | 15 | import com.qiniu.android.http.ResponseInfo; 16 | import com.sxu.smartpicture.choosepicture.ChoosePhotoDialog; 17 | import com.sxu.smartpicture.choosepicture.ChoosePhotoManager; 18 | import com.sxu.smartpicture.choosepicture.OnSimpleChoosePhotoListener; 19 | import com.sxu.smartpicture.utils.UploadUtils; 20 | 21 | import org.json.JSONObject; 22 | 23 | /** 24 | * @author Freeman 25 | * @date 2017/12/21 26 | */ 27 | 28 | 29 | public class ChooseAndCropImageActivity extends AppCompatActivity { 30 | 31 | private String filePath; 32 | 33 | @Override 34 | protected void onCreate(@Nullable Bundle savedInstanceState) { 35 | super.onCreate(savedInstanceState); 36 | setContentView(R.layout.activity_choose_and_crop_image_layout); 37 | Button chooseButton = (Button)findViewById(R.id.choose_button); 38 | Button uploadToServerButton = (Button)findViewById(R.id.upload_to_server_button); 39 | Button uploadToQNButton = (Button)findViewById(R.id.upload_to_qn_button); 40 | final ImageView imageView = (ImageView) findViewById(R.id.image); 41 | 42 | chooseButton.setOnClickListener(new View.OnClickListener() { 43 | @Override 44 | public void onClick(View v) { 45 | ChoosePhotoDialog dialog = new ChoosePhotoDialog(ChooseAndCropImageActivity.this, 46 | new String[] {"拍照", "从相册选择"}); 47 | dialog.show(); 48 | dialog.setOnItemListener(new AdapterView.OnItemClickListener() { 49 | @Override 50 | public void onItemClick(AdapterView adapterView, View view, int i, long l) { 51 | if (i == 0) { 52 | ChoosePhotoManager.getInstance().takePicture(ChooseAndCropImageActivity.this, true); 53 | } else { 54 | ChoosePhotoManager.getInstance().choosePhotoFromAlbum(ChooseAndCropImageActivity.this, true); 55 | } 56 | ChoosePhotoManager.getInstance().setChoosePhotoListener(new OnSimpleChoosePhotoListener() { 57 | @Override 58 | public void cropPhoto(Uri uri) { 59 | if (uri != null) { 60 | filePath = uri.getPath(); 61 | imageView.setImageURI(uri); 62 | } 63 | } 64 | }); 65 | } 66 | }); 67 | } 68 | }); 69 | 70 | uploadToServerButton.setOnClickListener(new View.OnClickListener() { 71 | @Override 72 | public void onClick(View v) { 73 | if (!TextUtils.isEmpty(filePath)) { 74 | UploadUtils.uploadToInnerServer(ChooseAndCropImageActivity.this, "http://m.baidu.com", 75 | filePath, new UploadUtils.OnUploadListener() { 76 | @Override 77 | public void onSuccess(String result) { 78 | Toast.makeText(ChooseAndCropImageActivity.this, "图片上传成功", Toast.LENGTH_SHORT).show(); 79 | } 80 | 81 | @Override 82 | public void onError(Exception e) { 83 | Toast.makeText(ChooseAndCropImageActivity.this, "图片上传失败" + e.getMessage(), Toast.LENGTH_SHORT).show(); 84 | } 85 | }); 86 | } else { 87 | Toast.makeText(ChooseAndCropImageActivity.this, "请先选择图片", Toast.LENGTH_SHORT).show(); 88 | } 89 | } 90 | }); 91 | 92 | uploadToQNButton.setOnClickListener(new View.OnClickListener() { 93 | @Override 94 | public void onClick(View v) { 95 | if (!TextUtils.isEmpty(filePath)) { 96 | UploadUtils.uploadToQiNiu(ChooseAndCropImageActivity.this, "", filePath, 97 | new UploadUtils.OnUploadToQiNiuListener() { 98 | @Override 99 | public void onCompleted(String key, ResponseInfo info, JSONObject res) { 100 | Toast.makeText(ChooseAndCropImageActivity.this, info.error, Toast.LENGTH_SHORT).show(); 101 | } 102 | }); 103 | } else { 104 | Toast.makeText(ChooseAndCropImageActivity.this, "请先选择图片", Toast.LENGTH_SHORT).show(); 105 | } 106 | } 107 | }); 108 | } 109 | 110 | @Override 111 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 112 | super.onActivityResult(requestCode, resultCode, data); 113 | ChoosePhotoManager.getInstance().onActivityResult(this, requestCode, data); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /app/src/main/java/com/sxu/imageset/ImageLoaderActivity.java: -------------------------------------------------------------------------------- 1 | package com.sxu.imageset; 2 | 3 | import android.graphics.Bitmap; 4 | import android.os.Bundle; 5 | import android.support.v4.view.ViewCompat; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.widget.TextView; 9 | import android.widget.Toast; 10 | 11 | import com.sxu.smartpicture.album.activity.PhotoPreviewActivity; 12 | import com.sxu.smartpicture.imageloader.ImageLoaderManager; 13 | import com.sxu.smartpicture.imageloader.WrapImageView; 14 | import com.sxu.smartpicture.imageloader.instance.FrescoInstance; 15 | import com.sxu.smartpicture.imageloader.instance.GlideInstance; 16 | import com.sxu.smartpicture.imageloader.instance.UILInstance; 17 | import com.sxu.smartpicture.imageloader.listener.ImageLoaderListener; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | 23 | /** 24 | * @author Freeman 25 | * @date 2017/12/19 26 | */ 27 | 28 | 29 | public class ImageLoaderActivity extends AppCompatActivity { 30 | 31 | private WrapImageView image; 32 | private WrapImageView blurImage; 33 | private WrapImageView rectangleImage; 34 | 35 | @Override 36 | protected void onCreate(Bundle savedInstanceState) { 37 | super.onCreate(savedInstanceState); 38 | setContentView(R.layout.activity_image_loader_layout); 39 | 40 | WrapImageView image = (WrapImageView) findViewById(R.id.image); 41 | WrapImageView blurImage = (WrapImageView) findViewById(R.id.blur_image); 42 | WrapImageView rectangleImage = (WrapImageView) findViewById(R.id.rectangle_image); 43 | WrapImageView circleImage = (WrapImageView) findViewById(R.id.circle_image); 44 | final TextView downloadText = findViewById(R.id.download_button); 45 | 46 | int type = getIntent().getIntExtra("type", 0); 47 | if (type == 0) { 48 | ImageLoaderManager.getInstance().init(getApplicationContext(), new FrescoInstance()); 49 | } else if (type == 1) { 50 | ImageLoaderManager.getInstance().init(getApplicationContext(), new UILInstance()); 51 | } else if (type == 2) { 52 | ImageLoaderManager.getInstance().init(getApplicationContext(), new GlideInstance()); 53 | } else { 54 | /** 55 | * Nothing 56 | */ 57 | } 58 | 59 | ViewCompat.setTransitionName(image, PhotoPreviewActivity.TRANSITION_NAME_PREFIX + "0"); 60 | ViewCompat.setTransitionName(blurImage, PhotoPreviewActivity.TRANSITION_NAME_PREFIX + "1"); 61 | ViewCompat.setTransitionName(rectangleImage, PhotoPreviewActivity.TRANSITION_NAME_PREFIX + "2"); 62 | ImageLoaderManager.getInstance().displayImage("http://t.cn/RTRKzUt", image); 63 | ImageLoaderManager.getInstance().displayImage("http://t.cn/RTRKzUt", blurImage); 64 | ImageLoaderManager.getInstance().displayImage("http://t.cn/RTRKzUt", rectangleImage); 65 | ImageLoaderManager.getInstance().displayImage("http://t.cn/RTRKJvS", circleImage); 66 | 67 | 68 | //ViewCompat.setTransitionName(image, PhotoPreviewActivity.TRANSITION_NAME_PREFIX + "0"); 69 | image.setOnClickListener(new View.OnClickListener() { 70 | @Override 71 | public void onClick(View v) { 72 | List photoList = new ArrayList<>(); 73 | photoList.add("http://t.cn/RTRKzUt"); 74 | photoList.add("http://img.tuku.cn/file_thumb/201602/m2016021513470744.jpg"); 75 | photoList.add("http://t.cn/RTRKzUt"); 76 | PhotoPreviewActivity.enter(ImageLoaderActivity.this, v, 0, photoList); 77 | } 78 | }); 79 | downloadText.setOnClickListener(new View.OnClickListener() { 80 | @Override 81 | public void onClick(View v) { 82 | ImageLoaderManager.getInstance().downloadImage(ImageLoaderActivity.this, 83 | "http://f8.topitme.com/8/0d/dd/1131049236b4ddd0d8o.jpg", new ImageLoaderListener() { 84 | @Override 85 | public void onStart() { 86 | 87 | } 88 | 89 | @Override 90 | public void onProcess(int completedSize, int totalSize) { 91 | float progress = completedSize * 1.0f / totalSize; 92 | if (progress < 1.0f) { 93 | downloadText.setText("已下载" + (progress * 100) + "%s"); 94 | } else { 95 | downloadText.setText("下载完成"); 96 | } 97 | } 98 | 99 | @Override 100 | public void onCompleted(Bitmap bitmap) { 101 | Toast.makeText(getBaseContext(), "下载成功", Toast.LENGTH_SHORT).show(); 102 | } 103 | 104 | @Override 105 | public void onFailure(Exception e) { 106 | Toast.makeText(getBaseContext(), "下载失败", Toast.LENGTH_SHORT).show(); 107 | } 108 | }); 109 | } 110 | }); 111 | } 112 | 113 | @Override 114 | protected void onDestroy() { 115 | super.onDestroy(); 116 | // 这里只是为了测试需要,使用时不需要调用 117 | ImageLoaderManager.getInstance().onDestroy(); 118 | } 119 | 120 | // @Override 121 | // public void onActivityReenter(int resultCode, Intent data) { 122 | // if (resultCode == RESULT_OK && data != null) { 123 | // final int currentIndex = data.getIntExtra("currentIndex", 0); 124 | // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 125 | // setExitSharedElementCallback(new SharedElementCallback() { 126 | // @Override 127 | // public void onMapSharedElements(List names, Map sharedElements) { 128 | // super.onMapSharedElements(names, sharedElements); 129 | // names.clear(); 130 | // sharedElements.clear(); 131 | // names.add(PhotoPreviewActivity.TRANSITION_NAME_PREFIX + currentIndex); 132 | // sharedElements.put(PhotoPreviewActivity.TRANSITION_NAME_PREFIX + currentIndex, blurImage); 133 | // } 134 | // }); 135 | // } 136 | // } 137 | // super.onActivityReenter(resultCode, data); 138 | // } 139 | } 140 | -------------------------------------------------------------------------------- /app/src/main/java/com/sxu/imageset/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.sxu.imageset; 2 | 3 | import android.Manifest; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.widget.RadioGroup; 9 | import android.widget.Toast; 10 | 11 | public class MainActivity extends AppCompatActivity implements View.OnClickListener { 12 | 13 | private int imageLoaderType; 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_main); 19 | 20 | View imageLoaderButton = findViewById(R.id.image_loader_button); 21 | View albumButton = findViewById(R.id.album_button); 22 | View chooseImageButton = findViewById(R.id.choose_image_button); 23 | RadioGroup radioGroup = (RadioGroup) findViewById(R.id.radioGroup); 24 | 25 | imageLoaderButton.setOnClickListener(this); 26 | albumButton.setOnClickListener(this); 27 | chooseImageButton.setOnClickListener(this); 28 | 29 | radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { 30 | @Override 31 | public void onCheckedChanged(RadioGroup group, int checkedId) { 32 | switch (group.getCheckedRadioButtonId()) { 33 | case R.id.fresco_radio: 34 | imageLoaderType = 0; 35 | break; 36 | case R.id.url_radio: 37 | imageLoaderType = 1; 38 | break; 39 | case R.id.glide_radio: 40 | imageLoaderType = 2; 41 | break; 42 | } 43 | } 44 | }); 45 | 46 | } 47 | 48 | @Override 49 | public void onClick(View v) { 50 | switch (v.getId()) { 51 | case R.id.image_loader_button: 52 | Intent intent = new Intent(this, ImageLoaderActivity.class); 53 | intent.putExtra("type", imageLoaderType); 54 | startActivity(intent); 55 | break; 56 | case R.id.album_button: 57 | AlbumActivity.enter(this, imageLoaderType); 58 | break; 59 | case R.id.choose_image_button: 60 | //test(); 61 | startActivity(new Intent(this, ChooseAndCropImageActivity.class)); 62 | break; 63 | default: 64 | break; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/arrow_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/src/main/res/drawable-xxhdpi/arrow_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/grid_item_selected_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/src/main/res/drawable-xxhdpi/grid_item_selected_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/grid_item_unselected_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/src/main/res/drawable-xxhdpi/grid_item_unselected_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/list_item_selected_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/src/main/res/drawable-xxhdpi/list_item_selected_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/list_item_unselected_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberuman/ImageSet/233f3361d2ddd515af91f297288a9818542caa90/app/src/main/res/drawable-xxhdpi/list_item_unselected_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/default_placeholder_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/grid_checkbox_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 16 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 56 | 61 | 66 | 71 | 76 | 81 | 86 | 91 | 96 | 101 | 106 | 111 | 116 | 121 | 126 | 131 | 136 | 141 | 146 | 151 | 156 | 161 | 166 | 171 | 172 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/list_checkbox_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/right_bottom_arrow_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_album_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 |