├── .gitignore ├── .travis.yml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── gun0912 │ │ └── tedbottompickerdemo │ │ ├── MainActivity.java │ │ └── MyApplication.java │ └── res │ ├── layout │ ├── activity_main.xml │ └── image_item.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── demo.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshot1.jpeg ├── screenshot_multi_select.jpeg ├── settings.gradle └── tedbottompicker ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src └── main ├── AndroidManifest.xml ├── java └── gun0912 │ └── tedbottompicker │ ├── GridSpacingItemDecoration.java │ ├── TedBottomPicker.java │ ├── TedBottomSheetDialogFragment.java │ ├── TedRxBottomPicker.java │ ├── adapter │ └── GalleryAdapter.java │ ├── util │ └── RealPathUtil.java │ └── view │ ├── TedEmptyRecyclerView.java │ ├── TedSquareFrameLayout.java │ └── TedSquareImageView.java └── res ├── drawable-hdpi ├── ic_camera.png └── ic_gallery.png ├── drawable-xhdpi ├── ic_camera.png ├── ic_clear.png └── ic_gallery.png ├── drawable-xxhdpi ├── ic_camera.png └── ic_gallery.png ├── drawable-xxxhdpi ├── gallery_photo_selected.xml ├── ic_camera.png ├── ic_gallery.png └── img_error.png ├── layout ├── tedbottompicker_content_view.xml ├── tedbottompicker_grid_item.xml └── tedbottompicker_selected_item.xml ├── values-ko └── strings.xml ├── values ├── attrs.xml ├── colors.xml ├── dimens.xml ├── strings.xml └── style.xml └── xml └── provider_paths.xml /.gitignore: -------------------------------------------------------------------------------- 1 | ###Android### 2 | 3 | # Built application files 4 | *.apk 5 | *.ap_ 6 | 7 | # Files for the Dalvik VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # Generated files 14 | bin/ 15 | gen/ 16 | 17 | # Gradle files 18 | .gradle/ 19 | build/ 20 | 21 | # Local configuration file (sdk path, etc) 22 | local.properties 23 | 24 | # Proguard folder generated by Eclipse 25 | proguard/ 26 | 27 | # Log Files 28 | *.log 29 | 30 | 31 | ###OSX### 32 | 33 | .DS_Store 34 | .AppleDouble 35 | .LSOverride 36 | 37 | # Icon must end with two \r 38 | Icon 39 | 40 | # Thumbnails 41 | ._* 42 | 43 | # Files that might appear on external disk 44 | .Spotlight-V100 45 | .Trashes 46 | 47 | # Directories potentially created on remote AFP share 48 | .AppleDB 49 | .AppleDesktop 50 | Network Trash Folder 51 | Temporary Items 52 | .apdisk 53 | 54 | 55 | ###Linux### 56 | 57 | *~ 58 | 59 | # KDE directory preferences 60 | .directory 61 | 62 | 63 | ###Windows### 64 | 65 | # Windows image file caches 66 | Thumbs.db 67 | ehthumbs.db 68 | 69 | # Folder config file 70 | Desktop.ini 71 | 72 | # Recycle Bin used on file shares 73 | $RECYCLE.BIN/ 74 | 75 | # Windows Installer files 76 | *.cab 77 | *.msi 78 | *.msm 79 | *.msp 80 | 81 | # Windows shortcuts 82 | *.lnk 83 | 84 | 85 | ###IntelliJ### 86 | 87 | *.iml 88 | *.ipr 89 | *.iws 90 | .idea/ 91 | 92 | 93 | ###Gradle### 94 | 95 | .gradle 96 | build/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | language: android 3 | jdk: oraclejdk8 4 | android: 5 | components: 6 | - tools 7 | - platform-tools 8 | - tools 9 | - android-27 10 | - build-tools-28.0.3 11 | - extra-android-m2repository 12 | - extra-google-m2repository 13 | script: 14 | - ./gradlew build 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [THIS LIBRARY IS DEPRECATED] Please use [TedImagePicker](https://github.com/ParkSangGwon/TedImagePicker) 2 |





3 | # What is TedBottomPicker? 4 | In Google's Material Design, Google introduce **Bottom sheets**.([Components – Bottom sheets](https://material.google.com/components/bottom-sheets.html))
5 | **Bottom sheets** slide up from the bottom of the screen to reveal more content. 6 | 7 | If you want pick image from gallery or take picture, this library can help easily.
8 | **TedBottomPicker** provide 3 options:
9 | 10 | 1. Take a picture by camera(using `MediaStore.ACTION_IMAGE_CAPTURE` intent) 11 | 2. Get image from gallery(using `Intent.ACTION_PICK` intent) 12 | 3. Get image from recent image(using `MediaStore.Images.Media.EXTERNAL_CONTENT_URI` cursor) 13 | 14 | 15 | **TedBottomPicker** is simple image picker using bottom sheet. 16 | 17 |

18 | ## TedImagePicker 19 | - If you want full screen image picker, use [TedImagePicker](https://github.com/ParkSangGwon/TedImagePicker) 20 | - TedImagePicker is simple/beautiful/smart image picker 21 | 22 | . 23 | 24 |

25 | ## Demo 26 | 1. Show Bottom Sheet. 27 | 2. Pick Image 28 | 29 | ### Single/Multi Select 30 | 31 | ![Screenshot](https://github.com/ParkSangGwon/TedBottomPicker/blob/master/screenshot1.jpeg?raw=true) ![Screenshot](https://github.com/ParkSangGwon/TedBottomPicker/blob/master/demo.gif?raw=true) 32 | ![Screenshot](https://github.com/ParkSangGwon/TedBottomPicker/blob/master/screenshot_multi_select.jpeg?raw=true) 33 | 34 | 35 | 36 | 37 | 38 | 39 | ## Setup 40 | 41 | 42 | ### Gradle 43 | [![Maven Central](https://img.shields.io/maven-central/v/io.github.ParkSangGwon/tedbottompicker.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.github.ParkSangGwon%22%20AND%20a:%tedbottompicker%22) 44 | ```javascript 45 | dependencies { 46 | implementation 'gun0912.ted:tedbottompicker:x.y.z' 47 | //implementation 'gun0912.ted:tedbottompicker:2.0.1' 48 | } 49 | 50 | ``` 51 | 52 | If you think this library is useful, please press star button at upside. 53 |
54 | 55 |

56 | 57 | 58 | 59 | ## How to use 60 | ### 1. Check Permission 61 | You have to grant `WRITE_EXTERNAL_STORAGE` permission from user.
62 | If your targetSDK version is 23+, you have to check permission and request permission to user.
63 | Because after Marshmallow(6.0), you have to not only declare permissions in `AndroidManifest.xml` but also request permissions at runtime.
64 | There are so many permission check library in [Android-Arsenal](http://android-arsenal.com/tag/235?sort=rating)
65 | I recommend [TedPermission](https://github.com/ParkSangGwon/TedPermission)
66 | **TedPermission** is super simple and smart permission check library.
67 |
68 | 69 | 70 | ### 2. Start TedBottomPicker 71 | - TedBottomPicker support `RxJava` and `Listener` style 72 |

73 | ### RxJava 74 | **You have to use TedRxBottomPicker** 75 | - Single image 76 | ```java 77 | TedRxBottomPicker.with(MainActivity.this) 78 | .show() 79 | .subscribe(uri -> 80 | // here is selected image uri 81 | }, Throwable::printStackTrace); 82 | 83 | 84 | ``` 85 | - Multi image 86 | ```java 87 | 88 | TedRxBottomPicker.with(MainActivity.this) 89 | //.setPeekHeight(getResources().getDisplayMetrics().heightPixels/2) 90 | .setPeekHeight(1600) 91 | .showTitle(false) 92 | .setCompleteButtonText("Done") 93 | .setEmptySelectionText("No Select") 94 | .setSelectedUriList(selectedUriList) 95 | .showMultiImage() 96 | .subscribe(uris -> { 97 | // here is selected image uri list 98 | }, Throwable::printStackTrace); 99 | 100 | ``` 101 | 102 |

103 | ### Listener 104 | **You have to use TedBottomPicker** 105 | - Single image 106 | ```java 107 | TedBottomPicker.with(MainActivity.this) 108 | .show(new TedBottomSheetDialogFragment.OnImageSelectedListener() { 109 | @Override 110 | public void onImageSelected(Uri uri) { 111 | // here is selected image uri 112 | } 113 | }); 114 | 115 | ``` 116 | 117 | - Multi image 118 | ```java 119 | TedBottomPicker.with(MainActivity.this) 120 | .setPeekHeight(1600) 121 | .showTitle(false) 122 | .setCompleteButtonText("Done") 123 | .setEmptySelectionText("No Select") 124 | .setSelectedUriList(selectedUriList) 125 | .showMultiImage(new TedBottomSheetDialogFragment.OnMultiImageSelectedListener() { 126 | @Override 127 | public void onImagesSelected(List uriList) { 128 | // here is selected image uri list 129 | } 130 | }); 131 | ``` 132 |
133 | 134 | ## Customize 135 | You can customize something ...
136 | 137 | ### Function 138 | 139 | #### Common 140 | 141 | * `showVideoMedia()` : Not only load image, but also load video 142 | * `setPreviewMaxCount(Int) (default: 25)` 143 | * `setPeekHeight(Int)` 144 | * `setPeekHeightResId(R.dimen.xxx)` 145 | * `showCameraTile(Boolean) (default: true)` 146 | * `setCameraTile(R.drawable.xxx or Drawable)` 147 | * `setCameraTileBackgroundResId(R.color.xxx)` 148 | * `setGalleryTile(R.drawable.xxx or Drawable)` 149 | * `showGalleryTile(Boolean) (default: true)` 150 | * `setGalleryTileBackgroundResId(R.color.xxx)` 151 | * `setSpacing(Int)` 152 | * `setSpacingResId(R.dimen.xxx)` 153 | * `setOnErrorListener(OnErrorListener)` 154 | * `setTitle(String or R.string.xxx) (default: 'Select Image','사진 선택')` 155 | * `showTitle(Boolean) (default: true)` 156 | * `setTitleBackgroundResId(R.color.xxx)` 157 | * `setImageProvider(ImageProvider)` 158 | : If you want load grid image yourself, you can use your ImageProvider 159 | 160 | #### Single Select 161 | * `setSelectedUri(Uri)` 162 | 163 | #### Multi Select 164 | * `setDeSelectIcon(R.drawable.xxx or Drawable)` 165 | * `setSelectedForeground(R.drawable.xxx or Drawable)` 166 | * `setSelectMaxCount(Int)` 167 | * `setSelectMinCount(Int)` 168 | * `setCompleteButtonText(String or R.string.xxx) (default: 'Done','완료')` 169 | * `setEmptySelectionText(String or R.string.xxx) (default: 'No Image','이미지가 선택되지 않았습니다')` 170 | * `setSelectMaxCountErrorText(String or R.string.xxx)` 171 | * `setSelectMinCountErrorText(String or R.string.xxx)` 172 | * `setSelectedUriList(ArrayList)` 173 | 174 |

175 | 176 | 177 | 178 | ## Thanks 179 | * [Flipboard-bottomsheet](https://github.com/Flipboard/bottomsheet) - Android component which presents a dismissible view from the bottom of the screen 180 | 181 | 182 | 183 | 184 |

185 | 186 | 187 | ## License 188 | ```code 189 | Copyright 2017 Ted Park 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License.``` 202 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | 5 | compileSdkVersion 27 6 | 7 | 8 | defaultConfig { 9 | applicationId "gun0912.tedbottompickerdemo" 10 | minSdkVersion 16 11 | targetSdkVersion 26 12 | versionCode 1 13 | versionName "1.0.0" 14 | multiDexEnabled true 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | 23 | lintOptions { 24 | abortOnError false 25 | } 26 | 27 | compileOptions { 28 | sourceCompatibility JavaVersion.VERSION_1_8 29 | targetCompatibility JavaVersion.VERSION_1_8 30 | } 31 | } 32 | 33 | 34 | repositories { 35 | 36 | 37 | } 38 | 39 | dependencies { 40 | implementation fileTree(include: ['*.jar'], dir: 'libs') 41 | testImplementation 'junit:junit:4.12' 42 | implementation 'com.android.support:appcompat-v7:27.1.1' 43 | implementation project(':tedbottompicker') 44 | implementation 'com.android.support:multidex:1.0.3' 45 | 46 | implementation 'gun0912.ted:tedpermission:2.2.0' 47 | implementation 'com.github.bumptech.glide:glide:4.7.1' 48 | annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1' 49 | 50 | debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3' 51 | releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3' 52 | 53 | implementation "io.reactivex.rxjava2:rxjava:2.2.6" 54 | } 55 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/TedPark/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/gun0912/tedbottompickerdemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package gun0912.tedbottompickerdemo; 2 | 3 | import android.Manifest; 4 | import android.net.Uri; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.util.Log; 8 | import android.util.TypedValue; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.widget.Button; 13 | import android.widget.FrameLayout; 14 | import android.widget.ImageView; 15 | import android.widget.Toast; 16 | 17 | import com.bumptech.glide.Glide; 18 | import com.bumptech.glide.RequestManager; 19 | import com.bumptech.glide.request.RequestOptions; 20 | import com.gun0912.tedpermission.PermissionListener; 21 | import com.gun0912.tedpermission.TedPermission; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | import gun0912.tedbottompicker.TedBottomPicker; 27 | import gun0912.tedbottompicker.TedRxBottomPicker; 28 | import io.reactivex.disposables.Disposable; 29 | 30 | public class MainActivity extends AppCompatActivity { 31 | 32 | private ImageView iv_image; 33 | private List selectedUriList; 34 | private Uri selectedUri; 35 | private Disposable singleImageDisposable; 36 | private Disposable multiImageDisposable; 37 | private ViewGroup mSelectedImagesContainer; 38 | private RequestManager requestManager; 39 | 40 | @Override 41 | protected void onCreate(Bundle savedInstanceState) { 42 | super.onCreate(savedInstanceState); 43 | setContentView(R.layout.activity_main); 44 | 45 | iv_image = findViewById(R.id.iv_image); 46 | mSelectedImagesContainer = findViewById(R.id.selected_photos_container); 47 | requestManager = Glide.with(this); 48 | setSingleShowButton(); 49 | setMultiShowButton(); 50 | setRxSingleShowButton(); 51 | setRxMultiShowButton(); 52 | 53 | } 54 | 55 | private void setSingleShowButton() { 56 | 57 | Button btnSingleShow = findViewById(R.id.btn_single_show); 58 | btnSingleShow.setOnClickListener(view -> { 59 | PermissionListener permissionlistener = new PermissionListener() { 60 | @Override 61 | public void onPermissionGranted() { 62 | 63 | TedBottomPicker.with(MainActivity.this) 64 | //.setPeekHeight(getResources().getDisplayMetrics().heightPixels/2) 65 | .setSelectedUri(selectedUri) 66 | //.showVideoMedia() 67 | .setPeekHeight(1200) 68 | .show(uri -> { 69 | Log.d("ted", "uri: " + uri); 70 | Log.d("ted", "uri.getPath(): " + uri.getPath()); 71 | selectedUri = uri; 72 | 73 | iv_image.setVisibility(View.VISIBLE); 74 | mSelectedImagesContainer.setVisibility(View.GONE); 75 | 76 | requestManager 77 | .load(uri) 78 | .into(iv_image); 79 | }); 80 | 81 | 82 | } 83 | 84 | @Override 85 | public void onPermissionDenied(ArrayList deniedPermissions) { 86 | Toast.makeText(MainActivity.this, "Permission Denied\n" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show(); 87 | } 88 | 89 | 90 | }; 91 | 92 | checkPermission(permissionlistener); 93 | }); 94 | } 95 | 96 | private void setMultiShowButton() { 97 | 98 | Button btnMultiShow = findViewById(R.id.btn_multi_show); 99 | btnMultiShow.setOnClickListener(view -> { 100 | 101 | PermissionListener permissionlistener = new PermissionListener() { 102 | @Override 103 | public void onPermissionGranted() { 104 | 105 | TedBottomPicker.with(MainActivity.this) 106 | //.setPeekHeight(getResources().getDisplayMetrics().heightPixels/2) 107 | .setPeekHeight(1600) 108 | .showTitle(false) 109 | .setCompleteButtonText("Done") 110 | .setEmptySelectionText("No Select") 111 | .setSelectedUriList(selectedUriList) 112 | .showMultiImage(uriList -> { 113 | selectedUriList = uriList; 114 | showUriList(uriList); 115 | }); 116 | 117 | 118 | } 119 | 120 | @Override 121 | public void onPermissionDenied(ArrayList deniedPermissions) { 122 | Toast.makeText(MainActivity.this, "Permission Denied\n" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show(); 123 | } 124 | 125 | 126 | }; 127 | 128 | checkPermission(permissionlistener); 129 | 130 | }); 131 | 132 | } 133 | 134 | 135 | private void setRxSingleShowButton() { 136 | 137 | Button btnSingleShow = findViewById(R.id.btn_rx_single_show); 138 | btnSingleShow.setOnClickListener(view -> { 139 | PermissionListener permissionlistener = new PermissionListener() { 140 | @Override 141 | public void onPermissionGranted() { 142 | 143 | singleImageDisposable = TedRxBottomPicker.with(MainActivity.this) 144 | //.setPeekHeight(getResources().getDisplayMetrics().heightPixels/2) 145 | .setSelectedUri(selectedUri) 146 | //.showVideoMedia() 147 | .setPeekHeight(1200) 148 | .show() 149 | .subscribe(uri -> { 150 | selectedUri = uri; 151 | 152 | iv_image.setVisibility(View.VISIBLE); 153 | mSelectedImagesContainer.setVisibility(View.GONE); 154 | 155 | requestManager 156 | .load(uri) 157 | .into(iv_image); 158 | }, Throwable::printStackTrace); 159 | 160 | 161 | } 162 | 163 | @Override 164 | public void onPermissionDenied(ArrayList deniedPermissions) { 165 | Toast.makeText(MainActivity.this, "Permission Denied\n" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show(); 166 | } 167 | 168 | 169 | }; 170 | 171 | checkPermission(permissionlistener); 172 | }); 173 | } 174 | 175 | 176 | private void setRxMultiShowButton() { 177 | 178 | Button btnRxMultiShow = findViewById(R.id.btn_rx_multi_show); 179 | btnRxMultiShow.setOnClickListener(view -> { 180 | PermissionListener permissionlistener = new PermissionListener() { 181 | @Override 182 | public void onPermissionGranted() { 183 | 184 | multiImageDisposable = TedRxBottomPicker.with(MainActivity.this) 185 | //.setPeekHeight(getResources().getDisplayMetrics().heightPixels/2) 186 | .setPeekHeight(1600) 187 | .showTitle(false) 188 | .setCompleteButtonText("Done") 189 | .setEmptySelectionText("No Select") 190 | .setSelectedUriList(selectedUriList) 191 | .showMultiImage() 192 | .subscribe(uris -> { 193 | selectedUriList = uris; 194 | showUriList(uris); 195 | }, Throwable::printStackTrace); 196 | 197 | 198 | } 199 | 200 | @Override 201 | public void onPermissionDenied(ArrayList deniedPermissions) { 202 | Toast.makeText(MainActivity.this, "Permission Denied\n" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show(); 203 | } 204 | 205 | 206 | }; 207 | 208 | checkPermission(permissionlistener); 209 | }); 210 | 211 | } 212 | 213 | private void checkPermission(PermissionListener permissionlistener) { 214 | TedPermission.with(MainActivity.this) 215 | .setPermissionListener(permissionlistener) 216 | .setDeniedMessage("If you reject permission,you can not use this service\n\nPlease turn on permissions at [Setting] > [Permission]") 217 | .setPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE) 218 | .check(); 219 | } 220 | 221 | private void showUriList(List uriList) { 222 | // Remove all views before 223 | // adding the new ones. 224 | mSelectedImagesContainer.removeAllViews(); 225 | 226 | iv_image.setVisibility(View.GONE); 227 | mSelectedImagesContainer.setVisibility(View.VISIBLE); 228 | 229 | int widthPixel = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics()); 230 | int heightPixel = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics()); 231 | 232 | 233 | for (Uri uri : uriList) { 234 | 235 | View imageHolder = LayoutInflater.from(this).inflate(R.layout.image_item, null); 236 | ImageView thumbnail = imageHolder.findViewById(R.id.media_image); 237 | 238 | requestManager 239 | .load(uri.toString()) 240 | .apply(new RequestOptions().fitCenter()) 241 | .into(thumbnail); 242 | 243 | mSelectedImagesContainer.addView(imageHolder); 244 | 245 | thumbnail.setLayoutParams(new FrameLayout.LayoutParams(widthPixel, heightPixel)); 246 | 247 | } 248 | 249 | } 250 | 251 | @Override 252 | protected void onDestroy() { 253 | if (singleImageDisposable != null && !singleImageDisposable.isDisposed()) { 254 | singleImageDisposable.dispose(); 255 | } 256 | if (multiImageDisposable != null && !multiImageDisposable.isDisposed()) { 257 | multiImageDisposable.dispose(); 258 | } 259 | super.onDestroy(); 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /app/src/main/java/gun0912/tedbottompickerdemo/MyApplication.java: -------------------------------------------------------------------------------- 1 | package gun0912.tedbottompickerdemo; 2 | 3 | import android.app.Application; 4 | import android.support.multidex.MultiDexApplication; 5 | 6 | import com.squareup.leakcanary.LeakCanary; 7 | 8 | public class MyApplication extends MultiDexApplication { 9 | 10 | @Override 11 | public void onCreate() { 12 | super.onCreate(); 13 | setLeakCanary(); 14 | } 15 | 16 | private void setLeakCanary() { 17 | if (LeakCanary.isInAnalyzerProcess(this)) { 18 | // This process is dedicated to LeakCanary for heap analysis. 19 | // You should not init your app in this process. 20 | return; 21 | } 22 | LeakCanary.install(this); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 |