Home

Awesome

FishBun

Android Arsenal Build Status codecov Maven Central

<p style="float:left;"> <a href="https://play.google.com/store/apps/details?id=com.sangcomz.fishbundemo"> <img HEIGHT="40" WIDTH="135" alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/apps/en-play-badge.png" /> </a> </p>

FishBun is a highly customizable image picker for Android.

<img src="/pic/fishbuns.png">

What's New in FishBun? :tada:

Customizable Styles

FishBun supports various visual styles and allows fine-tuning for details. Just to show some examples:

Default

Code
FishBun.with(WithActivityActivity.this)
        .setImageAdapter(new GlideAdapter())
        .startAlbumWithOnActivityResult(requestCode) or startAlbumWithActivityResultCallback(activityResultLauncher); 
Screenshots

<img src="/pic/default1.png" width="30%"> <img src="/pic/default2.png" width="30%"> <img src="/pic/default3.png" width="30%">

Dark

Code
FishBun.with(WithActivityActivity.this)
        .setImageAdapter(new GlideAdapter())
        .setMaxCount(5)
        .setMinCount(3)
        .setPickerSpanCount(5)
        .setActionBarColor(Color.parseColor("#795548"), Color.parseColor("#5D4037"), false)
        .setActionBarTitleColor(Color.parseColor("#ffffff"))
        .setArrayPaths(path)
        .setAlbumSpanCount(2, 3)
        .setButtonInAlbumActivity(false)
        .setCamera(true)
        .exceptGif(true)
        .setReachLimitAutomaticClose(true)
        .setHomeAsUpIndicatorDrawable(ContextCompat.getDrawable(this, R.drawable.ic_custom_back_white))
        .setDoneButtonDrawable(ContextCompat.getDrawable(this, R.drawable.ic_custom_ok))
        .setAllDoneButtonDrawable(ContextCompat.getDrawable(this, R.drawable.ic_custom_ok))
        .setIsUseAllDoneButton(ContextCompat.getDrawable(this, R.drawable.ic_custom_ok))
        .setAllViewTitle("All")
        .setMenuAllDoneText("All Done")
        .setActionBarTitle("FishBun Dark")
        .textOnNothingSelected("Please select three or more!")
        .exceptMimeType(listOf(MimeType.GIF))
        .setSpecifyFolderList(arrayListOf("Screenshots", "Camera"))
        .startAlbumWithOnActivityResult(requestCode);
Screenshots

<img src="/pic/dark1.png" width="30%"> <img src="/pic/dark2.png" width="30%"> <img src="/pic/dark3.png" width="30%">

Light

Code
FishBun.with(WithActivityActivity.this)
        .setImageAdapter(new GlideAdapter())
        .setPickerCount(50)
        .setPickerSpanCount(4)
        .setActionBarColor(Color.parseColor("#ffffff"), Color.parseColor("#ffffff"), true)
        .setActionBarTitleColor(Color.parseColor("#000000"))
        .setArrayPaths(path)
        .setAlbumSpanCount(1, 2)
        .setButtonInAlbumActivity(true)
        .setCamera(false)
        .exceptGif(true)
        .setReachLimitAutomaticClose(false)
        .setHomeAsUpIndicatorDrawable(ContextCompat.getDrawable(this, R.drawable.ic_arrow_back_black_24dp))
        .setOkButtonDrawable(ContextCompat.getDrawable(this, R.drawable.ic_check_black_24dp))
        .setAllViewTitle("All of your photos")
        .setActionBarTitle("FishBun Light")
        .textOnImagesSelectionLimitReached("You can't select any more.")
        .textOnNothingSelected("I need a photo!")
        .startAlbumWithOnActivityResult(requestCode);
Screenshots

<img src="/pic/light1.png" width="30%"> <img src="/pic/light2.png" width="30%"> <img src="/pic/light3.png" width="30%">

How to Setup

Fishbun 0.10.0 and above only supports projects that have been migrated to androidx. For more information, read Google's migration guide.

Setting up FishBun requires to add this Gradle configuration:

dependencies {
    implementation 'io.github.sangcomz:fishbun:x.x.x'
     
    implementation 'io.coil-kt:coil:0.11.0'
    or
    implementation 'com.github.bumptech.glide:glide:4.11.0'

} 

and to allow the following permissions in your Manifest:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

If your app targets Android 11 with compileSdk/targetSdk >= 30 then you will need to add this to the manifest (outside of the application block) in order to capture pictures with the device camera. Android documentation here:

<queries>
    <intent>
        <action android:name="android.media.action.IMAGE_CAPTURE" />
    </intent>
</queries>

If your app targets Android 13 with compileSdk/targetSdk >= 33 then you will need to add this to the manifest. Android documentation here:

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

<uses-permission
    android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />

How to Use

Use FishBun in an activity:

FishBun.with(YourActivity).setImageAdapter(new GlideAdapter()).startAlbumWithOnActivityResult(requestCode);

or in a fragment:

FishBun.with(YourFragment).setImageAdapter(new CoilAdapter()).startAlbumWithOnActivityResult(reqeustCode);

and implement OnActivityResult:

protected void onActivityResult(int requestCode, int resultCode,
                                Intent imageData) {
    super.onActivityResult(requestCode, resultCode, imageData);
    switch (requestCode) {
        case FishBun.FISHBUN_REQUEST_CODE:
            if (resultCode == RESULT_OK) {
                // path = imageData.getStringArrayListExtra(Define.INTENT_PATH);
                // you can get an image path(ArrayList<String>) on <0.6.2

                path = imageData.getParcelableArrayListExtra(INTENT_PATH);
                // you can get an image path(ArrayList<Uri>) on 0.6.2 and later
                break;
            }
    }
}

Various customizable features can be controlled by chained methods as in:

FishBun.with(YourActivity or YourFragment)
        .setImageAdapter(new GlideAdapter())
        .setIsUseDetailView(false)
        .setPickerCount(5) //Deprecated
        .setMaxCount(5)
        .setMinCount(1)
        .setPickerSpanCount(6)
        .setActionBarColor(Color.parseColor("#795548"), Color.parseColor("#5D4037"), false)
        .setActionBarTitleColor(Color.parseColor("#ffffff"))
        .setArrayPaths(path)
        .setAlbumSpanCount(2, 4)
        .setButtonInAlbumActivity(false)
        .setCamera(true)
        .setReachLimitAutomaticClose(true)
        .setHomeAsUpIndicatorDrawable(ContextCompat.getDrawable(this, R.drawable.ic_custom_back_white))
        .setOkButtonDrawable(ContextCompat.getDrawable(this, R.drawable.ic_custom_ok))
        .setAllViewTitle("All")
        .setActionBarTitle("Image Library")
        .textOnImagesSelectionLimitReached("Limit Reached!")
        .textOnNothingSelected("Nothing Selected")
        .setSelectCircleStrokeColor(Color.BLACK)
        .isStartInAllView(false)
        .exceptMimeType(listOf(MimeType.GIF))
        .setSpecifyFolderList(arrayListOf("Screenshots", "Camera"))
        .startAlbumWithOnActivityResult(requestCode);

attribute

      Method Name      Description                                Default Value  
setSelectedImagesSet the already selected imagenull
setMaxCountMaximum number of images selected10
setMinCountMinimum number of images selected1
setRequestCodeSet RequestCode27
setReachLimitAutomaticClosePicker automatically ends when the number of images is selectedfalse
exceptMimeTypeSet file type to exclude(gif, png, jpeg, bmp, webp)NONE
setAlbumThumbnailSizeThumbnail size of album screen70dp
setPickerSpanCountSet the picker's span count4
setActionBarColorSet background color of action bar, statusBar color, set light theme#3F51B5, #303F9F, false
setActionBarTitleColorSet the title color of the action bar#ffffff
textOnNothingSelectedMessage when nothing is selected"There is no selected image."
textOnImagesSelectionLimitReachedMessage when the image is already all selected"Selection full. Deselect an image to choose another."
setButtonInAlbumActivitySet Selected button visibility in album screenfalse
setAlbumSpanCountSet the album's span count1, 2
setAlbumSpanCountOnlyLandscapeSet the album's span count when landscape2
setAlbumSpanCountOnlPortraitSet the album's span count when portrait1
setAllViewTitleSet the name of all views"All view"
setActionBarTitleSet the title of the action bar"Album"
setHomeAsUpIndicatorDrawableCustomizing back button of the action barnull
setDoneButtonDrawableCustomizing done button of the action barnull
setAllDoneButtonDrawableCustomizing all done button of the action barnull
setIsUseAllDoneButtonSet whether to use the all select buttonfalse
setMenuDoneTextSet text for Done buttonnull
setMenuAllDoneTextSet text for All Done buttonnull
setMenuTextColorSet text color for menuInteger.MAX_VALUE
setIsUseDetailViewSet whether to use detail screenfalse
setIsShowCountSet whether to show counting numbersfalse
setSelectCircleStrokeColorSet select circle color#c1ffffff
isStartInAllViewSet to start with all viewfalse
setSpecifyFolderListSet folder to showNONE
hasCameraInPickerPageSet whether to use the camera button on picker screenfalse

Android M Permission

Running on Android M, FishBun checks if it has proper permission for you before reading an external storage.

<img src="/pic/permission.png" width="20%">

Apps using FishBun

If you are using this library in your app, let me know.

Project NameResult Screen
Pandaz(unavailable now) <p style="float:left;"><img src="/pic/pandaz_result.gif">
Multi photo resize compress crop in batch PicTools <p style="float:left;"> <a href="https://play.google.com/store/apps/details?id=omkar.tenkale.pictoolsandroid&hl=en_US"> <img HEIGHT="40" WIDTH="135" alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/apps/en-play-badge.png" /></a></p><img src="/pic/multi_photo_result.gif">

Contribution

Any suggestions or contributions would be welcomed. CONTRIBUTING

Feedback

Bug reports and feature requests can be submitted here (please read the instructions on how to report a bug and request feature).

License

Copyright 2019 Seokwon Jeong

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.