├── .gitignore ├── LICENSE.txt ├── README.md ├── app ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── net │ │ └── yazeed44 │ │ └── multiimagepicker │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── net │ │ └── yazeed44 │ │ └── multiimagepicker │ │ └── MainActivity.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── layout │ └── activity_main.xml │ ├── menu │ └── menu_about.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── integers.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── imagepicker ├── build.gradle ├── gradlew ├── gradlew.bat ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── net │ │ └── yazeed44 │ │ └── library │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── net │ │ └── yazeed44 │ │ └── imagepicker │ │ ├── model │ │ ├── AlbumEntry.java │ │ └── ImageEntry.java │ │ ├── ui │ │ ├── AlbumsAdapter.java │ │ ├── AlbumsFragment.java │ │ ├── ImagePagerAdapter.java │ │ ├── ImagesPagerFragment.java │ │ ├── ImagesThumbnailAdapter.java │ │ ├── ImagesThumbnailFragment.java │ │ ├── PickerActivity.java │ │ ├── SpacesItemDecoration.java │ │ └── SquareFrameLayout.java │ │ └── util │ │ ├── CameraSupport.java │ │ ├── Events.java │ │ ├── LoadingAlbumsRequest.java │ │ ├── OfflineSpiceService.java │ │ ├── Picker.java │ │ └── Util.java │ └── res │ ├── drawable-hdpi │ ├── ic_action_camera_white.png │ ├── ic_action_done_white.png │ └── ic_play_arrow.png │ ├── drawable-mdpi │ ├── ic_action_camera_white.png │ ├── ic_action_done_white.png │ └── ic_play_arrow.png │ ├── drawable-xhdpi │ ├── ic_action_camera_white.png │ ├── ic_action_done_white.png │ └── ic_play_arrow.png │ ├── drawable-xxhdpi │ ├── ic_action_camera_white.png │ ├── ic_action_done_white.png │ └── ic_play_arrow.png │ ├── drawable-xxxhdpi │ ├── ic_action_camera_white.png │ ├── ic_action_done_white.png │ └── ic_play_arrow.png │ ├── drawable │ └── image_border.xml │ ├── layout │ ├── activity_pick.xml │ ├── element_album.xml │ ├── element_image.xml │ ├── fragment_album_browse.xml │ ├── fragment_image_browse.xml │ └── fragment_image_pager.xml │ ├── menu │ ├── menu_deselect_all.xml │ ├── menu_select_all.xml │ └── menu_take_photo.xml │ ├── values-ar │ └── strings.xml │ ├── values-ko │ └── strings.xml │ ├── values-land │ ├── dimens.xml │ └── integers.xml │ ├── values-pt │ └── strings.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── integers.xml │ ├── strings.xml │ └── styles.xml ├── screenshots ├── albums.png └── photos.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # IDE files 3 | .idea/ 4 | *.iml 5 | 6 | # Project build and temp files 7 | .gradle 8 | build/ 9 | /local.properties 10 | 11 | # OS specific files 12 | .DS_Store 13 | .fuse_hidden* 14 | 15 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 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 | #Notice 2 | -Picker.Builder(Context,Listener) has been replaced with (Context,Listener,themeResId) and it's highely recommended to use the new constructor 3 | 4 | -``` onPickedSuccessfully(String[] paths)``` has been replaced with ``` onPickedSuccessfully(ArrayList images)``` 5 | 6 | -The sample in google play and screenshots are out-of-date , will update them on 1.2 or 1.3 version 7 | 8 | MultiImagePicker 9 | ================ 10 | 11 | A library to pick multi images With features like setting limit and UI that goes nicely with your app theme 12 | 13 | Sample App (On playstore) : https://play.google.com/store/apps/details?id=net.yazeed44.imagepicker.sample 14 | 15 | This library is built-in gallery to pick multiple images or capture new photos , and retrieve the path in the code 16 | 17 | 18 | This library is inspired by Telegram image picker 19 | 20 | 21 | ![Demo](screenshots/albums.png) ![Demo](screenshots/photos.png) 22 | 23 | 24 | 25 | :app is the sample application 26 | 27 | 28 | :imagepicker is the library source code 29 | 30 | Gradle Dependency (jCenter) 31 | ========================== 32 | Just add the dependency to your build.gradle file 33 | ```gradle 34 | compile 'net.yazeed44.imagepicker:imagepicker:1.3.1' 35 | ``` 36 | 37 | [ ![Download](https://api.bintray.com/packages/yazeed44/maven/multi-image-picker/images/download.svg) ](https://bintray.com/yazeed44/maven/multi-image-picker/_latestVersion) 38 | 39 | Also don't forget to add [cwac-cam2](https://github.com/commonsguy/cwac-cam2) repository by declaring this in your ```build.gradle``` 40 | 41 | ```gradle 42 | repositories { 43 | maven { 44 | url "https://repo.commonsware.com.s3.amazonaws.com" 45 | } 46 | } 47 | 48 | ``` 49 | 50 | 51 | ### If jCenter is Having Issues (the library can't be resolved) 52 | 53 | Add this to your app's build.gradle file: 54 | 55 | ```Gradle 56 | repositories { 57 | maven { url 'https://dl.bintray.com/yazeed44/maven' } 58 | } 59 | ``` 60 | 61 | 62 | Getting started 63 | ========== 64 | 65 | It's easy 66 | 67 | -Define a style that uses a toolbar instead of actionbar , if you have already has a style who does that skip this step 68 | ```xml 69 | 75 | ``` 76 | 77 | ```java 78 | private void pickImages(){ 79 | 80 | //You can change many settings in builder like limit , Pick mode and colors 81 | new Picker.Builder(this,new MyPickListener(),R.style.MIP_theme) 82 | .build() 83 | .startActivity(); 84 | 85 | } 86 | 87 | private class MyPickListener implements Picker.PickListener { 88 | 89 | @Override 90 | public void onPickedSuccessfully(final ArrayList images) { 91 | doSomethingWithImages(images); 92 | } 93 | 94 | @Override 95 | public void onCancel() { 96 | //User canceled the pick activity 97 | } 98 | } 99 | ``` 100 | 101 | ## Make Photo/Video capture optional 102 | 103 | In order to capture photos and videos the library depends on [cwac-cam2](https://github.com/commonsguy/cwac-cam2) library. 104 | If you just want to pick images from gallery you can disable the capture feature by excluding the `cwac-cam2` library from your module: 105 | 106 | ```gradle 107 | compile('net.yazeed44.imagepicker:imagepicker:1.3.1') { 108 | exclude module: 'cam2' 109 | } 110 | // or 111 | configurations.compile.exclude module: 'cam2' 112 | ``` 113 | 114 | ##Contribution 115 | 116 | ### Questions 117 | 118 | If you have any questions regarding MultiImagePicker,create an Issue 119 | 120 | ### Feature request 121 | 122 | To create a new Feature request, open an issue 123 | 124 | I'll try to answer as soon as I find the time. 125 | 126 | ### Pull requests welcome 127 | 128 | Feel free to contribute to MultiImagePicker. 129 | 130 | Either you found a bug or have created a new and awesome feature, just create a pull request. 131 | 132 | 133 | ### Discuss 134 | Join in the conversation , [Join us in telegram](https://telegram.me/joinchat/013dbd2b01ae8b2dcdb1147ac067c9ae). 135 | 136 | 137 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion '23.0.2' 6 | 7 | defaultConfig { 8 | applicationId "net.yazeed44.imagepicker.sample" 9 | minSdkVersion 15 10 | targetSdkVersion 23 11 | versionCode 3 12 | versionName "1.3.1" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | 21 | packagingOptions { 22 | exclude 'META-INF/LICENSE.txt' 23 | exclude 'META-INF/NOTICE.txt' 24 | } 25 | 26 | 27 | } 28 | 29 | 30 | repositories { 31 | maven { url "https://jitpack.io" } 32 | } 33 | 34 | 35 | dependencies { 36 | compile fileTree(include: ['*.jar'], dir: 'libs') 37 | compile project(':imagepicker') 38 | compile('com.github.afollestad.material-dialogs:core:0.8.5.3@aar') { 39 | transitive = true 40 | } 41 | } 42 | 43 | // Remove comment to exclude cwac-cam2 dependency to make the capture feature unavailable 44 | //configurations.compile.exclude module: 'cam2' 45 | -------------------------------------------------------------------------------- /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 /home/yazeed44/Desktop/downloadLinux/android-studio (2)/android-sdk-linux/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/androidTest/java/net/yazeed44/multiimagepicker/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package net.yazeed44.multiimagepicker; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/net/yazeed44/multiimagepicker/MainActivity.java: -------------------------------------------------------------------------------- 1 | package net.yazeed44.multiimagepicker; 2 | 3 | 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.GridLayoutManager; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | import android.support.v7.widget.RecyclerView; 9 | import android.text.Html; 10 | import android.text.Spanned; 11 | import android.util.Log; 12 | import android.view.Menu; 13 | import android.view.MenuItem; 14 | import android.view.View; 15 | import android.view.ViewGroup; 16 | import android.widget.AbsListView; 17 | import android.widget.ImageView; 18 | import android.widget.Toast; 19 | 20 | import com.afollestad.materialdialogs.MaterialDialog; 21 | import com.bumptech.glide.Glide; 22 | 23 | import net.yazeed44.imagepicker.model.ImageEntry; 24 | import net.yazeed44.imagepicker.sample.R; 25 | import net.yazeed44.imagepicker.util.Picker; 26 | 27 | import java.util.ArrayList; 28 | 29 | 30 | public class MainActivity extends AppCompatActivity implements Picker.PickListener { 31 | 32 | private static final String TAG = "Sample activity"; 33 | private RecyclerView mImageSampleRecycler; 34 | private ArrayList mSelectedImages; 35 | 36 | @Override 37 | protected void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_main); 40 | 41 | 42 | mImageSampleRecycler = (RecyclerView) findViewById(R.id.images_sample); 43 | setupRecycler(); 44 | 45 | 46 | } 47 | 48 | private void setupRecycler() { 49 | 50 | final GridLayoutManager gridLayoutManager = new GridLayoutManager(this, getResources().getInteger(R.integer.num_columns_image_samples)); 51 | gridLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); 52 | mImageSampleRecycler.setLayoutManager(gridLayoutManager); 53 | 54 | 55 | } 56 | 57 | 58 | public void onClickPickImageSingle(View view) { 59 | 60 | new Picker.Builder(this, this, R.style.MIP_theme) 61 | .setPickMode(Picker.PickMode.SINGLE_IMAGE) 62 | .build() 63 | .startActivity(); 64 | } 65 | 66 | public void onClickPickImageMultipleWithLimit(View view) { 67 | new Picker.Builder(this, this, R.style.MIP_theme) 68 | .setPickMode(Picker.PickMode.MULTIPLE_IMAGES) 69 | .setLimit(6) 70 | .build() 71 | .startActivity(); 72 | } 73 | 74 | public void onPickImageMultipleInfinite(View view) { 75 | new Picker.Builder(this, this, R.style.MIP_theme) 76 | .setPickMode(Picker.PickMode.MULTIPLE_IMAGES) 77 | .build() 78 | .startActivity(); 79 | 80 | } 81 | 82 | public void onClickPickImageWithVideos(View view) { 83 | new Picker.Builder(this, this, R.style.MIP_theme) 84 | .setPickMode(Picker.PickMode.MULTIPLE_IMAGES) 85 | .setVideosEnabled(true) 86 | .build() 87 | .startActivity(); 88 | 89 | } 90 | 91 | 92 | @Override 93 | public boolean onCreateOptionsMenu(Menu menu) { 94 | // Inflate the menu; this adds items to the action bar if it is present. 95 | getMenuInflater().inflate(R.menu.menu_about, menu); 96 | return true; 97 | } 98 | 99 | @Override 100 | public boolean onOptionsItemSelected(MenuItem item) { 101 | // Handle action bar item clicks here. The action bar will 102 | // automatically handle clicks on the Home/Up button, so long 103 | // as you specify a parent activity in AndroidManifest.xml. 104 | final int id = item.getItemId(); 105 | 106 | 107 | if (id == R.id.action_about) { 108 | showAbout(); 109 | return true; 110 | } 111 | 112 | return super.onOptionsItemSelected(item); 113 | } 114 | 115 | private void showAbout() { 116 | 117 | final Spanned aboutBody = Html.fromHtml(getResources().getString(R.string.about_body_html)); 118 | 119 | 120 | new MaterialDialog.Builder(this) 121 | .title(R.string.about_title) 122 | .content(aboutBody) 123 | .contentLineSpacing(1.6f) 124 | .show(); 125 | 126 | 127 | } 128 | 129 | 130 | 131 | 132 | 133 | 134 | @Override 135 | public void onPickedSuccessfully(ArrayList images) { 136 | mSelectedImages = images; 137 | setupImageSamples(); 138 | Log.d(TAG, "Picked images " + images.toString()); 139 | } 140 | 141 | private void setupImageSamples() { 142 | mImageSampleRecycler.setAdapter(new ImageSamplesAdapter()); 143 | } 144 | 145 | @Override 146 | public void onCancel() { 147 | Log.i(TAG, "User canceled picker activity"); 148 | Toast.makeText(this, "User canceld picker activtiy", Toast.LENGTH_SHORT).show(); 149 | 150 | } 151 | 152 | 153 | private class ImageSamplesAdapter extends RecyclerView.Adapter { 154 | 155 | 156 | @Override 157 | public ImageSampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 158 | final ImageView imageView = new ImageView(parent.getContext()); 159 | return new ImageSampleViewHolder(imageView); 160 | } 161 | 162 | @Override 163 | public void onBindViewHolder(ImageSampleViewHolder holder, int position) { 164 | 165 | final String path = mSelectedImages.get(position).path; 166 | loadImage(path, holder.thumbnail); 167 | } 168 | 169 | @Override 170 | public int getItemCount() { 171 | return mSelectedImages.size(); 172 | } 173 | 174 | 175 | private void loadImage(final String path, final ImageView imageView) { 176 | imageView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 440)); 177 | 178 | Glide.with(MainActivity.this) 179 | .load(path) 180 | .asBitmap() 181 | .into(imageView); 182 | 183 | 184 | } 185 | 186 | 187 | } 188 | 189 | class ImageSampleViewHolder extends RecyclerView.ViewHolder { 190 | 191 | protected ImageView thumbnail; 192 | 193 | public ImageSampleViewHolder(View itemView) { 194 | super(itemView); 195 | thumbnail = (ImageView) itemView; 196 | } 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yazeed44/MultiImagePicker/a85c2f4b1d2ade11b97db83302658c99a6ca2bfa/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yazeed44/MultiImagePicker/a85c2f4b1d2ade11b97db83302658c99a6ca2bfa/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yazeed44/MultiImagePicker/a85c2f4b1d2ade11b97db83302658c99a6ca2bfa/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yazeed44/MultiImagePicker/a85c2f4b1d2ade11b97db83302658c99a6ca2bfa/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 |