From b025122978acb7613fe6df3bc1a1efc08a05357d Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 19 Jan 2017 16:33:36 +0800 Subject: [PATCH] init commit --- .gitignore | 85 + app/.gitignore | 1 + app/build.gradle | 30 + app/proguard-rules.pro | 17 + .../imagepicker/ExampleInstrumentedTest.java | 26 + app/src/main/AndroidManifest.xml | 22 + .../imnjh/imagepickersample/MainActivity.java | 102 + .../ScaleTypeFillCenterInside.java | 33 + .../SingleFileLimitInterceptor.java | 93 + .../adapter/PickAdapter.java | 77 + .../app/PickerApplication.java | 32 + .../imnjh/imagepickersample/cache/Cache.java | 23 + .../imagepickersample/cache/CacheManager.java | 64 + .../imagepickersample/cache/InnerCache.java | 71 + .../imagepickersample/cache/LocalCache.java | 89 + .../imageloader/FrescoImageLoader.java | 83 + .../imageloader/GlideImageLoader.java | 40 + .../widget/ExpandGridView.java | 30 + app/src/main/res/drawable/image_bg.xml | 9 + app/src/main/res/layout/activity_main.xml | 73 + app/src/main/res/layout/image_item.xml | 13 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 4458 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2406 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 5742 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 10402 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 15964 bytes app/src/main/res/values-w820dp/dimens.xml | 6 + app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/dimens.xml | 5 + app/src/main/res/values/strings.xml | 4 + .../imnjh/imagepicker/ExampleUnitTest.java | 17 + build.gradle | 39 + imagepicker/.gitignore | 1 + imagepicker/build.gradle | 31 + imagepicker/proguard-rules.pro | 17 + imagepicker/src/main/AndroidManifest.xml | 37 + .../imnjh/imagepicker/CapturePhotoHelper.java | 134 + .../imagepicker/FileChooseInterceptor.java | 14 + .../com/imnjh/imagepicker/ImageLoader.java | 20 + .../com/imnjh/imagepicker/PickerAction.java | 7 + .../com/imnjh/imagepicker/PickerConfig.java | 63 + .../com/imnjh/imagepicker/SImagePicker.java | 135 + .../activity/BasePickerActivity.java | 47 + .../activity/CaptureConfirmActivity.java | 84 + .../activity/CaptureTempActivity.java | 86 + .../activity/CropImageActivity.java | 181 + .../activity/PhotoPickerActivity.java | 311 ++ .../activity/PickerPreviewActivity.java | 587 ++++ .../imagepicker/adapter/AlbumAdapter.java | 73 + .../adapter/BaseRecycleCursorAdapter.java | 245 ++ .../adapter/CommonHeaderFooterAdapter.java | 202 ++ .../imagepicker/adapter/PhotoAdapter.java | 197 ++ .../imagepicker/control/AlbumController.java | 85 + .../control/BaseLoaderController.java | 31 + .../imagepicker/control/PhotoController.java | 141 + .../imnjh/imagepicker/loader/AlbumLoader.java | 62 + .../imnjh/imagepicker/loader/PhotoLoader.java | 55 + .../com/imnjh/imagepicker/model/Album.java | 95 + .../com/imnjh/imagepicker/model/Photo.java | 74 + .../imagepicker/util/CollectionUtils.java | 31 + .../imnjh/imagepicker/util/DeviceCompat.java | 76 + .../com/imnjh/imagepicker/util/FileUtil.java | 137 + .../com/imnjh/imagepicker/util/ImageUtil.java | 394 +++ .../com/imnjh/imagepicker/util/LogUtils.java | 171 + .../imnjh/imagepicker/util/SystemUtil.java | 127 + .../com/imnjh/imagepicker/util/UriUtil.java | 77 + .../imnjh/imagepicker/widget/CheckBox.java | 288 ++ .../widget/ClipImageBorderView.java | 67 + .../imagepicker/widget/ClipImageLayout.java | 53 + .../imagepicker/widget/ClipZoomImageView.java | 345 ++ .../widget/GridInsetDecoration.java | 33 + .../widget/PickerBottomLayout.java | 100 + .../widget/PicturePreviewPageView.java | 81 + .../imagepicker/widget/PreviewViewPager.java | 74 + .../widget/SquareRelativeLayout.java | 55 + .../widget/subsamplingview/ImageSource.java | 233 ++ .../subsamplingview/ImageViewState.java | 55 + .../subsamplingview/OnImageEventListener.java | 57 + .../SubsamplingScaleImageView.java | 3051 +++++++++++++++++ .../decoder/CompatDecoderFactory.java | 22 + .../decoder/DecoderFactory.java | 13 + .../subsamplingview/decoder/ImageDecoder.java | 26 + .../decoder/ImageRegionDecoder.java | 50 + .../decoder/SkiaImageDecoder.java | 82 + .../decoder/SkiaImageRegionDecoder.java | 111 + .../src/main/res/anim/slide_in_bottom.xml | 8 + .../drawable-xxhdpi/bg_spinner_default.9.png | Bin 0 -> 1027 bytes .../drawable-xxhdpi/ic_album_tick_blue.png | Bin 0 -> 1218 bytes .../drawable-xxhdpi/ic_attachment_camera.png | Bin 0 -> 2972 bytes .../res/drawable-xxhdpi/ic_general_back.png | Bin 0 -> 532 bytes .../ic_general_cancel_left.png | Bin 0 -> 666 bytes .../ic_maillist_mailbox_arrow.png | Bin 0 -> 317 bytes .../drawable-xxhdpi/ic_takephoto_again.png | Bin 0 -> 1896 bytes .../res/drawable-xxhdpi/ic_takephoto_ok.png | Bin 0 -> 1377 bytes .../res/drawable-xxhdpi/ic_takephoto_quit.png | Bin 0 -> 914 bytes .../main/res/drawable/bg_toolbar_spinner.xml | 5 + .../src/main/res/drawable/bs_selectable.xml | 10 + .../main/res/drawable/ic_arrow_down_white.xml | 6 + .../main/res/layout/activity_capture_temp.xml | 11 + .../main/res/layout/activity_crop_image.xml | 39 + .../res/layout/activity_photo_confirm.xml | 51 + .../main/res/layout/activity_photo_picker.xml | 38 + .../res/layout/activity_picker_preview.xml | 70 + .../src/main/res/layout/album_list_item.xml | 26 + .../res/layout/common_toolbar_spinner.xml | 7 + .../main/res/layout/item_album_selected.xml | 18 + .../main/res/layout/item_picker_capture.xml | 13 + .../main/res/layout/picker_bottom_layout.xml | 45 + .../src/main/res/layout/picker_photo_item.xml | 19 + .../src/main/res/values-v19/styles.xml | 9 + imagepicker/src/main/res/values/attrs.xml | 24 + imagepicker/src/main/res/values/colors.xml | 22 + imagepicker/src/main/res/values/dimens.xml | 5 + imagepicker/src/main/res/values/strings.xml | 11 + imagepicker/src/main/res/values/styles.xml | 59 + settings.gradle | 1 + 116 files changed, 10411 insertions(+) create mode 100644 .gitignore create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/imnjh/imagepicker/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/imnjh/imagepickersample/MainActivity.java create mode 100644 app/src/main/java/com/imnjh/imagepickersample/ScaleTypeFillCenterInside.java create mode 100644 app/src/main/java/com/imnjh/imagepickersample/SingleFileLimitInterceptor.java create mode 100644 app/src/main/java/com/imnjh/imagepickersample/adapter/PickAdapter.java create mode 100644 app/src/main/java/com/imnjh/imagepickersample/app/PickerApplication.java create mode 100644 app/src/main/java/com/imnjh/imagepickersample/cache/Cache.java create mode 100644 app/src/main/java/com/imnjh/imagepickersample/cache/CacheManager.java create mode 100644 app/src/main/java/com/imnjh/imagepickersample/cache/InnerCache.java create mode 100644 app/src/main/java/com/imnjh/imagepickersample/cache/LocalCache.java create mode 100644 app/src/main/java/com/imnjh/imagepickersample/imageloader/FrescoImageLoader.java create mode 100644 app/src/main/java/com/imnjh/imagepickersample/imageloader/GlideImageLoader.java create mode 100644 app/src/main/java/com/imnjh/imagepickersample/widget/ExpandGridView.java create mode 100644 app/src/main/res/drawable/image_bg.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/image_item.xml create mode 100755 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/values-w820dp/dimens.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/test/java/com/imnjh/imagepicker/ExampleUnitTest.java create mode 100644 build.gradle create mode 100644 imagepicker/.gitignore create mode 100644 imagepicker/build.gradle create mode 100644 imagepicker/proguard-rules.pro create mode 100644 imagepicker/src/main/AndroidManifest.xml create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/CapturePhotoHelper.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/FileChooseInterceptor.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/ImageLoader.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/PickerAction.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/PickerConfig.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/SImagePicker.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/activity/BasePickerActivity.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/activity/CaptureConfirmActivity.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/activity/CaptureTempActivity.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/activity/CropImageActivity.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/activity/PhotoPickerActivity.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/activity/PickerPreviewActivity.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/adapter/AlbumAdapter.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/adapter/BaseRecycleCursorAdapter.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/adapter/CommonHeaderFooterAdapter.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/adapter/PhotoAdapter.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/control/AlbumController.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/control/BaseLoaderController.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/control/PhotoController.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/loader/AlbumLoader.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/loader/PhotoLoader.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/model/Album.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/model/Photo.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/util/CollectionUtils.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/util/DeviceCompat.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/util/FileUtil.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/util/ImageUtil.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/util/LogUtils.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/util/SystemUtil.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/util/UriUtil.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/CheckBox.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/ClipImageBorderView.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/ClipImageLayout.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/ClipZoomImageView.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/GridInsetDecoration.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/PickerBottomLayout.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/PicturePreviewPageView.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/PreviewViewPager.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/SquareRelativeLayout.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/subsamplingview/ImageSource.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/subsamplingview/ImageViewState.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/subsamplingview/OnImageEventListener.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/subsamplingview/SubsamplingScaleImageView.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/subsamplingview/decoder/CompatDecoderFactory.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/subsamplingview/decoder/DecoderFactory.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/subsamplingview/decoder/ImageDecoder.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/subsamplingview/decoder/ImageRegionDecoder.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/subsamplingview/decoder/SkiaImageDecoder.java create mode 100644 imagepicker/src/main/java/com/imnjh/imagepicker/widget/subsamplingview/decoder/SkiaImageRegionDecoder.java create mode 100644 imagepicker/src/main/res/anim/slide_in_bottom.xml create mode 100644 imagepicker/src/main/res/drawable-xxhdpi/bg_spinner_default.9.png create mode 100644 imagepicker/src/main/res/drawable-xxhdpi/ic_album_tick_blue.png create mode 100644 imagepicker/src/main/res/drawable-xxhdpi/ic_attachment_camera.png create mode 100644 imagepicker/src/main/res/drawable-xxhdpi/ic_general_back.png create mode 100644 imagepicker/src/main/res/drawable-xxhdpi/ic_general_cancel_left.png create mode 100644 imagepicker/src/main/res/drawable-xxhdpi/ic_maillist_mailbox_arrow.png create mode 100644 imagepicker/src/main/res/drawable-xxhdpi/ic_takephoto_again.png create mode 100644 imagepicker/src/main/res/drawable-xxhdpi/ic_takephoto_ok.png create mode 100644 imagepicker/src/main/res/drawable-xxhdpi/ic_takephoto_quit.png create mode 100644 imagepicker/src/main/res/drawable/bg_toolbar_spinner.xml create mode 100644 imagepicker/src/main/res/drawable/bs_selectable.xml create mode 100644 imagepicker/src/main/res/drawable/ic_arrow_down_white.xml create mode 100644 imagepicker/src/main/res/layout/activity_capture_temp.xml create mode 100644 imagepicker/src/main/res/layout/activity_crop_image.xml create mode 100644 imagepicker/src/main/res/layout/activity_photo_confirm.xml create mode 100644 imagepicker/src/main/res/layout/activity_photo_picker.xml create mode 100644 imagepicker/src/main/res/layout/activity_picker_preview.xml create mode 100644 imagepicker/src/main/res/layout/album_list_item.xml create mode 100644 imagepicker/src/main/res/layout/common_toolbar_spinner.xml create mode 100644 imagepicker/src/main/res/layout/item_album_selected.xml create mode 100644 imagepicker/src/main/res/layout/item_picker_capture.xml create mode 100644 imagepicker/src/main/res/layout/picker_bottom_layout.xml create mode 100644 imagepicker/src/main/res/layout/picker_photo_item.xml create mode 100644 imagepicker/src/main/res/values-v19/styles.xml create mode 100644 imagepicker/src/main/res/values/attrs.xml create mode 100644 imagepicker/src/main/res/values/colors.xml create mode 100644 imagepicker/src/main/res/values/dimens.xml create mode 100644 imagepicker/src/main/res/values/strings.xml create mode 100644 imagepicker/src/main/res/values/styles.xml create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de060f4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,85 @@ +## http://stackoverflow.com/questions/16736856/what-should-be-in-my-gitignore-for-an-android-studio-project +## https://raw.githubusercontent.com/github/gitignore/master/Android.gitignore + +gradle.properties + +# Built application files +*.apk +*.ap_ + +# Files for the Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# Windows thumbnail db +Thumbs.db + +# OSX files +.DS_Store + +# Eclipse project files +.classpath +.project +.metadata/ + +# Android Studio +*.iml +.idea +#.idea/workspace.xml - remove # and delete .idea if it better suit your needs. + +# Gradle files +.gradle/ +.gradle +build/ + +#NDK +obj/ + + +# Optional - for older project format, add this section to your gitignore file: +/*/out +/*/*/build +/*/*/production +*.iws +*.ipr +*~ +*.swp + + +# Update: Since Android Studio 1.0, new projects are created with this gitignore file: +/local.properties +/.idea/workspace.xml +/.idea/libraries +/build + + +# Intellij IDEA (see https://intellij-support.jetbrains.com/entries/23393067) +.idea/workspace.xml +.idea/tasks.xml +.idea/datasources.xml +.idea/dataSources.ids + +gradle/ +gradlew +gradlew.bat diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..42b54e3 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,30 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion + + defaultConfig { + applicationId "com.imnjh.imagepickersample" + minSdkVersion rootProject.ext.minSdk + targetSdkVersion rootProject.ext.targetSdk + versionCode 1 + versionName "1.0" + ndk { + abiFilters "armeabi" + } + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile project(':imagepicker') + compile 'com.github.bumptech.glide:glide:3.7.0' + compile 'com.facebook.fresco:fresco:0.10.0+' + compile 'com.facebook.fresco:imagepipeline-okhttp3:0.10.0+' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..874fae7 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/niejunhong/Develop/android-sdk-macosx/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/com/imnjh/imagepicker/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/imnjh/imagepicker/ExampleInstrumentedTest.java new file mode 100644 index 0000000..27998b7 --- /dev/null +++ b/app/src/androidTest/java/com/imnjh/imagepicker/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.imnjh.imagepicker; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.imnjh.imagepicker", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..0bcfec4 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/imnjh/imagepickersample/MainActivity.java b/app/src/main/java/com/imnjh/imagepickersample/MainActivity.java new file mode 100644 index 0000000..be09ff3 --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/MainActivity.java @@ -0,0 +1,102 @@ +package com.imnjh.imagepickersample; + +import java.util.ArrayList; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.View; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.GridView; +import android.widget.TextView; + +import com.imnjh.imagepicker.SImagePicker; +import com.imnjh.imagepicker.activity.PhotoPickerActivity; +import com.imnjh.imagepickersample.adapter.PickAdapter; +import com.imnjh.imagepickersample.cache.CacheManager; + +public class MainActivity extends AppCompatActivity { + + public static final String AVATAR_FILE_NAME = "avatar.png"; + public static final int REQUEST_CODE_AVATAR = 100; + public static final int REQUEST_CODE_IMAGE = 101; + + private Button pickHeadBtn; + private Button pickImageBtn; + private Button pickImageWithLimitBtn; + private GridView gridView; + private PickAdapter pickAdapter; + private TextView originalView; + private CheckBox showCamera; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + initUI(); + } + + private void initUI() { + pickAdapter = new PickAdapter(this); + gridView = (GridView) findViewById(R.id.image_grid); + gridView.setAdapter(pickAdapter); + showCamera = (CheckBox) findViewById(R.id.show_camera); + originalView = (TextView) findViewById(R.id.original); + pickHeadBtn = (Button) findViewById(R.id.pick_head_icon); + pickImageBtn = (Button) findViewById(R.id.pick_image); + pickImageWithLimitBtn = (Button) findViewById(R.id.pick_image_with_limit); + pickHeadBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + SImagePicker + .from(MainActivity.this) + .pickMode(SImagePicker.MODE_AVATAR) + .showCamera(showCamera.isChecked()) + .cropFilePath( + CacheManager.getInstance().getImageInnerCache() + .getAbsolutePath(AVATAR_FILE_NAME)) + .forResult(REQUEST_CODE_AVATAR); + } + }); + pickImageBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + SImagePicker + .from(MainActivity.this) + .maxCount(9) + .rowCount(3) + .showCamera(showCamera.isChecked()) + .pickMode(SImagePicker.MODE_IMAGE) + .forResult(REQUEST_CODE_IMAGE); + } + }); + pickImageWithLimitBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + SImagePicker + .from(MainActivity.this) + .maxCount(9) + .rowCount(3) + .pickMode(SImagePicker.MODE_IMAGE) + .fileInterceptor(new SingleFileLimitInterceptor()) + .forResult(REQUEST_CODE_IMAGE); + } + }); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == Activity.RESULT_OK) { + final ArrayList pathList = + data.getStringArrayListExtra(PhotoPickerActivity.EXTRA_RESULT_SELECTION); + final boolean original = + data.getBooleanExtra(PhotoPickerActivity.EXTRA_RESULT_ORIGINAL, false); + pickAdapter.setNewData(pathList); + originalView.setText("原图:" + original); + } + } +} diff --git a/app/src/main/java/com/imnjh/imagepickersample/ScaleTypeFillCenterInside.java b/app/src/main/java/com/imnjh/imagepickersample/ScaleTypeFillCenterInside.java new file mode 100644 index 0000000..863c40d --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/ScaleTypeFillCenterInside.java @@ -0,0 +1,33 @@ +package com.imnjh.imagepickersample; + +import android.graphics.Matrix; +import android.graphics.Rect; + +import com.facebook.drawee.drawable.ScalingUtils; + +/** + * Created on 6/6/16. + * + * @author yingyi.xu@rush.im (Yingyi Xu) + */ +public class ScaleTypeFillCenterInside extends ScalingUtils.AbstractScaleType { + + public static final ScalingUtils.ScaleType INSTANCE = new ScaleTypeFillCenterInside(); + + @Override + public void getTransformImpl( + Matrix outTransform, + Rect parentRect, + int childWidth, + int childHeight, + float focusX, + float focusY, + float scaleX, + float scaleY) { + float scale = Math.min(scaleX, scaleY); + float dx = parentRect.left + (parentRect.width() - childWidth * scale) * 0.5f; + float dy = parentRect.top + (parentRect.height() - childHeight * scale) * 0.5f; + outTransform.setScale(scale, scale); + outTransform.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f)); + } +} diff --git a/app/src/main/java/com/imnjh/imagepickersample/SingleFileLimitInterceptor.java b/app/src/main/java/com/imnjh/imagepickersample/SingleFileLimitInterceptor.java new file mode 100644 index 0000000..cc41861 --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/SingleFileLimitInterceptor.java @@ -0,0 +1,93 @@ +package com.imnjh.imagepickersample; + +import java.io.File; +import java.util.ArrayList; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Parcel; + +import com.imnjh.imagepicker.FileChooseInterceptor; +import com.imnjh.imagepicker.PickerAction; + +/** + * Created by Martin on 2017/1/18. + */ + +public class SingleFileLimitInterceptor implements FileChooseInterceptor { + + private static final long MAX_FILE_SIZE_ORIGINAL = 200 * 1024; // 200K + + public SingleFileLimitInterceptor() {} + + @Override + public boolean onFileChosen(Context context, ArrayList selectedPic, + boolean original, + int resultCode, PickerAction action) { + if (resultCode != Activity.RESULT_OK) { + return true; + } + if (original) { + ArrayList confirmedFiles = new ArrayList<>(); + for (String filePath : selectedPic) { + File file = new File(filePath); + if (file.exists()) { + if (file.length() <= MAX_FILE_SIZE_ORIGINAL) { + confirmedFiles.add(filePath); + } + } + } + if (confirmedFiles.size() < selectedPic.size()) { + showSingleFileLimitDialog(context, original, resultCode, action, confirmedFiles); + return false; + } + } + return true; + } + + private void showSingleFileLimitDialog(Context context, final boolean original, + final int resultCode, + final PickerAction action, final ArrayList confirmedFiles) { + new AlertDialog.Builder(context) + .setMessage(R.string.general_max_per_image) + .setPositiveButton( + R.string.general_ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + action.proceedResultAndFinish(confirmedFiles, original, resultCode); + } + }) + .setNegativeButton(R.string.general_cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) {} + }) + .show(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + + } + + protected SingleFileLimitInterceptor(Parcel in) {} + + public static final Creator CREATOR = + new Creator() { + @Override + public SingleFileLimitInterceptor createFromParcel(Parcel source) { + return new SingleFileLimitInterceptor(source); + } + + @Override + public SingleFileLimitInterceptor[] newArray(int size) { + return new SingleFileLimitInterceptor[size]; + } + }; +} diff --git a/app/src/main/java/com/imnjh/imagepickersample/adapter/PickAdapter.java b/app/src/main/java/com/imnjh/imagepickersample/adapter/PickAdapter.java new file mode 100644 index 0000000..eca0cab --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/adapter/PickAdapter.java @@ -0,0 +1,77 @@ +package com.imnjh.imagepickersample.adapter; + +import java.util.ArrayList; +import java.util.List; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.imnjh.imagepickersample.R; +import com.imnjh.imagepickersample.app.PickerApplication; + +/** + * Created by Martin on 2017/1/18. + */ + +public class PickAdapter extends BaseAdapter { + + private LayoutInflater layoutInflater; + private List data = new ArrayList<>(); + + public PickAdapter(Context context) { + layoutInflater = LayoutInflater.from(context); + } + + public void setNewData(List data) { + this.data.clear(); + if (data != null) { + this.data.addAll(data); + } + notifyDataSetChanged(); + } + + + @Override + public int getCount() { + return data.size(); + } + + @Override + public Object getItem(int position) { + return data.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder holder; + if (convertView == null) { + convertView = layoutInflater.inflate(R.layout.image_item, null, false); + holder = new ViewHolder(); + holder.imageView = (ImageView) convertView.findViewById(R.id.image); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + holder.imageView.setImageResource(R.drawable.ic_album_tick_blue); + Glide.with(PickerApplication.getAppContext()).load(data.get(position)).skipMemoryCache(true) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .dontAnimate().into(holder.imageView); + return convertView; + } + + + class ViewHolder { + public ImageView imageView; + } +} diff --git a/app/src/main/java/com/imnjh/imagepickersample/app/PickerApplication.java b/app/src/main/java/com/imnjh/imagepickersample/app/PickerApplication.java new file mode 100644 index 0000000..2d33263 --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/app/PickerApplication.java @@ -0,0 +1,32 @@ +package com.imnjh.imagepickersample.app; + +import android.app.Application; +import android.content.Context; + +import com.imnjh.imagepicker.PickerConfig; +import com.imnjh.imagepicker.SImagePicker; +import com.imnjh.imagepickersample.R; +import com.imnjh.imagepickersample.imageloader.FrescoImageLoader; + +/** + * Created by Martin on 2017/1/17. + */ + +public class PickerApplication extends Application { + + private static Application instance; + + @Override + public void onCreate() { + super.onCreate(); + instance = this; + SImagePicker.init(new PickerConfig.Builder().setAppContext(this) + .setImageLoader(new FrescoImageLoader()) + .setToolbaseColor(getColor(R.color.colorPrimary)).build()); + } + + + public static Context getAppContext() { + return instance; + } +} diff --git a/app/src/main/java/com/imnjh/imagepickersample/cache/Cache.java b/app/src/main/java/com/imnjh/imagepickersample/cache/Cache.java new file mode 100644 index 0000000..7ea552b --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/cache/Cache.java @@ -0,0 +1,23 @@ +package com.imnjh.imagepickersample.cache; + +import java.io.File; + +import com.imnjh.imagepicker.util.FileUtil; + +/** + * Created by Martin on 2017/1/17. + */ +public abstract class Cache { + + public abstract boolean exist(String fileName); + + public abstract String getAbsolutePath(String fileName); + + public abstract File getDirectory(); + + public abstract boolean deleteCacheItem(String fileName); + + public void clear() { + FileUtil.deleteDirectory(getDirectory()); + } +} diff --git a/app/src/main/java/com/imnjh/imagepickersample/cache/CacheManager.java b/app/src/main/java/com/imnjh/imagepickersample/cache/CacheManager.java new file mode 100644 index 0000000..18fefc5 --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/cache/CacheManager.java @@ -0,0 +1,64 @@ +package com.imnjh.imagepickersample.cache; + +import com.imnjh.imagepickersample.app.PickerApplication; +import com.imnjh.imagepicker.util.SystemUtil; + +import java.io.File; +/** + * Created by Martin on 2017/1/17. + */ +public class CacheManager { + + public static final String ROOT_STORE = "PickerSample"; + + private InnerCache imageInnerCache; + + private LocalCache imageCache; + + private static CacheManager instance; + + private CacheManager() { + init(); + } + + public static synchronized CacheManager getInstance() { + if (instance == null) { + instance = new CacheManager(); + } + return instance; + } + + + private void init() { + initRootCache(SystemUtil.getStoreDir(PickerApplication.getAppContext())); + } + + private boolean initRootCache(File storage) { + File cacheRoot = new File(storage, ROOT_STORE); + boolean isMkRoot = true; + if (!cacheRoot.exists()) { + isMkRoot = cacheRoot.mkdirs(); + } else if (!cacheRoot.isDirectory()) { + isMkRoot = false; + } + if (!isMkRoot) { + return false; + } + return true; + } + + public InnerCache getImageInnerCache() { + if (imageInnerCache == null) { + imageInnerCache = new InnerCache(); + + } + return imageInnerCache; + } + + public LocalCache getImageCache() { + if (imageCache == null) { + imageCache = new LocalCache("Image"); + } + return imageCache; + } +} diff --git a/app/src/main/java/com/imnjh/imagepickersample/cache/InnerCache.java b/app/src/main/java/com/imnjh/imagepickersample/cache/InnerCache.java new file mode 100644 index 0000000..f163f69 --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/cache/InnerCache.java @@ -0,0 +1,71 @@ +package com.imnjh.imagepickersample.cache; + +import java.io.File; + +import android.content.Context; +import android.os.Environment; + +import com.imnjh.imagepickersample.app.PickerApplication; +import com.imnjh.imagepicker.util.FileUtil; + +/** + * Created by Martin on 2017/1/17. + */ +public class InnerCache extends Cache { + + private File innerCache; + + public InnerCache() { + innerCache = getCacheDirCreateIfNotExist(); + } + + private File getCacheDirCreateIfNotExist() { + File cachePath = new File(getInnerCacheDir(PickerApplication.getAppContext())); + if (!cachePath.isDirectory()) { + try { + cachePath.mkdirs(); + } catch (Exception e) { + e.printStackTrace(); + } + try { + new File(cachePath, ".nomedia").createNewFile(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return cachePath; + } + + private String getInnerCacheDir(Context context) { + String cachePath; + if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) + || !Environment.isExternalStorageRemovable()) { + cachePath = context.getExternalCacheDir().getPath(); + } else { + cachePath = context.getCacheDir().getPath(); + } + return cachePath; + } + + + public boolean exist(String fileName) { + String path = innerCache + File.separator + fileName; + return FileUtil.exist(path); + } + + @Override + public String getAbsolutePath(String fileName) { + return getDirectory().getAbsolutePath() + File.separator + fileName; + } + + @Override + public File getDirectory() { + return getCacheDirCreateIfNotExist(); + } + + @Override + public boolean deleteCacheItem(String fileName) { + String filePath = getAbsolutePath(fileName); + return FileUtil.deleteFile(filePath); + } +} diff --git a/app/src/main/java/com/imnjh/imagepickersample/cache/LocalCache.java b/app/src/main/java/com/imnjh/imagepickersample/cache/LocalCache.java new file mode 100644 index 0000000..e601581 --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/cache/LocalCache.java @@ -0,0 +1,89 @@ +package com.imnjh.imagepickersample.cache; + +import java.io.File; +import java.io.IOException; + +import com.imnjh.imagepicker.util.FileUtil; +import com.imnjh.imagepicker.util.LogUtils; +import com.imnjh.imagepicker.util.SystemUtil; +import com.imnjh.imagepickersample.app.PickerApplication; + +/** + * Created by Martin on 2017/1/17. + */ +public final class LocalCache extends Cache { + + private final String dataName; + + private final String dataPath; + + /** + * @param dataName cache directory name + */ + public LocalCache(String dataName) { + this.dataName = dataName; + StringBuilder pathBuilder = new StringBuilder(getRushCachePath()); + pathBuilder.append(File.separatorChar); + pathBuilder.append(getDataName()); + pathBuilder.append(File.separatorChar); + dataPath = pathBuilder.toString(); + initCacheRoot(dataPath); + } + + + + private String getRushCachePath() { + File dataDir = SystemUtil.getStoreDir(PickerApplication.getAppContext()); + return getDirectoryCreateIfNotExist( + dataDir.getPath() + File.separator + CacheManager.ROOT_STORE) + .getPath(); + } + + private File getDirectoryCreateIfNotExist(String pathStr) { + File file = new File(pathStr); + if (!file.isDirectory()) { + file.mkdirs(); + } + return file; + } + + @Override + public File getDirectory() { + return getDirectoryCreateIfNotExist(dataPath); + } + + + @Override + public String getAbsolutePath(String fileName) { + return getDirectory() + File.separator + fileName; + } + + @Override + public boolean deleteCacheItem(String fileName) { + String filePath = getAbsolutePath(fileName); + return FileUtil.deleteFile(filePath); + } + + @Override + public boolean exist(String relativePath) { + String filePath = getAbsolutePath(relativePath); + boolean ret = FileUtil.exist(filePath); + return ret; + } + + public String getDataName() { + return dataName; + } + + + private void initCacheRoot(String root) { + getDirectoryCreateIfNotExist(root); + File ignoreFile = new File(root, ".nomedia"); + try { + ignoreFile.createNewFile(); + } catch (IOException e) { + LogUtils.e(LocalCache.class.getSimpleName(), "Failed to create ignore file.", e); + } + } + +} diff --git a/app/src/main/java/com/imnjh/imagepickersample/imageloader/FrescoImageLoader.java b/app/src/main/java/com/imnjh/imagepickersample/imageloader/FrescoImageLoader.java new file mode 100644 index 0000000..589e470 --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/imageloader/FrescoImageLoader.java @@ -0,0 +1,83 @@ +package com.imnjh.imagepickersample.imageloader; + +import okhttp3.OkHttpClient; + +import android.content.Context; +import android.net.Uri; +import android.widget.ImageView; + +import com.facebook.cache.disk.DiskCacheConfig; +import com.facebook.drawee.backends.pipeline.Fresco; +import com.facebook.drawee.interfaces.DraweeController; +import com.facebook.drawee.view.DraweeView; +import com.facebook.drawee.view.SimpleDraweeView; +import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory; +import com.facebook.imagepipeline.common.ResizeOptions; +import com.facebook.imagepipeline.core.ImagePipelineConfig; +import com.facebook.imagepipeline.request.ImageRequest; +import com.facebook.imagepipeline.request.ImageRequestBuilder; +import com.imnjh.imagepicker.ImageLoader; +import com.imnjh.imagepickersample.app.PickerApplication; +import com.imnjh.imagepickersample.ScaleTypeFillCenterInside; +import com.imnjh.imagepickersample.cache.CacheManager; + +/** + * Created by Martin on 2017/1/17. + */ + +public class FrescoImageLoader implements ImageLoader { + + public FrescoImageLoader() { + init(); + } + + private void init() { + DiskCacheConfig diskCacheConfig = + DiskCacheConfig + .newBuilder(PickerApplication.getAppContext()) + .setBaseDirectoryPath( + CacheManager.getInstance().getImageCache() + .getDirectory()) + .build(); + ImagePipelineConfig config = + OkHttpImagePipelineConfigFactory + .newBuilder( + PickerApplication.getAppContext(), + new OkHttpClient.Builder().build()) + .setDownsampleEnabled(true).setMainDiskCacheConfig(diskCacheConfig) + .build(); + Fresco.initialize(PickerApplication.getAppContext(), config); + } + + @Override + public void bindImage(ImageView photoImageView, Uri uri, int width, int height) { + DraweeView draweeView = (DraweeView) photoImageView; + final ImageRequestBuilder requestBuilder = ImageRequestBuilder.newBuilderWithSource(uri); + if (width > 0 && height > 0) { + requestBuilder.setResizeOptions(new ResizeOptions(width, height)); + } + ImageRequest imageRequest = requestBuilder.build(); + DraweeController controller = Fresco.newDraweeControllerBuilder() + .setOldController(draweeView.getController()) + .setImageRequest(imageRequest).build(); + draweeView.setController(controller); + } + + @Override + public void bindImage(ImageView imageView, Uri uri) { + bindImage(imageView, uri, 0, 0); + } + + @Override + public ImageView createImageView(Context context) { + SimpleDraweeView simpleDraweeView = new SimpleDraweeView(context); + return simpleDraweeView; + } + + @Override + public ImageView createFakeImageView(Context context) { + SimpleDraweeView fakeImage = new SimpleDraweeView(context); + fakeImage.getHierarchy().setActualImageScaleType(ScaleTypeFillCenterInside.INSTANCE); + return fakeImage; + } +} diff --git a/app/src/main/java/com/imnjh/imagepickersample/imageloader/GlideImageLoader.java b/app/src/main/java/com/imnjh/imagepickersample/imageloader/GlideImageLoader.java new file mode 100644 index 0000000..372309f --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/imageloader/GlideImageLoader.java @@ -0,0 +1,40 @@ +package com.imnjh.imagepickersample.imageloader; + +import android.content.Context; +import android.net.Uri; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.imnjh.imagepicker.ImageLoader; +import com.imnjh.imagepickersample.R; +import com.imnjh.imagepickersample.app.PickerApplication; + +/** + * Created by Martin on 2017/1/18. + */ + +public class GlideImageLoader implements ImageLoader { + @Override + public void bindImage(ImageView imageView, Uri uri, int width, int height) { + Glide.with(PickerApplication.getAppContext()).load(uri).placeholder(R.mipmap.ic_launcher) + .error(R.mipmap.ic_launcher).override(width, height).dontAnimate().into(imageView); + } + + @Override + public void bindImage(ImageView imageView, Uri uri) { + Glide.with(PickerApplication.getAppContext()).load(uri).placeholder(R.mipmap.ic_launcher) + .error(R.mipmap.ic_launcher).dontAnimate().into(imageView); + } + + @Override + public ImageView createImageView(Context context) { + ImageView imageView = new ImageView(context); + imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + return imageView; + } + + @Override + public ImageView createFakeImageView(Context context) { + return new ImageView(context); + } +} diff --git a/app/src/main/java/com/imnjh/imagepickersample/widget/ExpandGridView.java b/app/src/main/java/com/imnjh/imagepickersample/widget/ExpandGridView.java new file mode 100644 index 0000000..aaafde2 --- /dev/null +++ b/app/src/main/java/com/imnjh/imagepickersample/widget/ExpandGridView.java @@ -0,0 +1,30 @@ +package com.imnjh.imagepickersample.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.ViewGroup; +import android.widget.GridView; + +public class ExpandGridView extends GridView { + public ExpandGridView(Context context) { + super(context); + } + + public ExpandGridView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public ExpandGridView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + + @Override + public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, + MeasureSpec.AT_MOST); + super.onMeasure(widthMeasureSpec, expandSpec); + ViewGroup.LayoutParams params = getLayoutParams(); + params.height = getMeasuredHeight(); + } +} diff --git a/app/src/main/res/drawable/image_bg.xml b/app/src/main/res/drawable/image_bg.xml new file mode 100644 index 0000000..77ef7e4 --- /dev/null +++ b/app/src/main/res/drawable/image_bg.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..e0c6bdc --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,73 @@ + + + + + + + + + +