Git Product home page Git Product logo

bottomsheet-imagepicker's Introduction

Release Build Status

BottomSheet Image Picker for Android

A modern image picker implemented as BottomSheet.

Single Selection Demo 1โ€ƒ Single Selection Demo 2โ€ƒ Multi Selection Demo 1

Features

  1. select single/multiple images right in the bottom sheet
  2. use camera to take a picture
  3. choose image from gallery app
  4. handles all permission requests

This library is based on BSImagePicker. I reimplemented everything in Kotlin and added some features. Also, I used the new androidX artifacts.

How to Use

Minimum SDK: 17

Add to Project

First make sure jitpack is included as a repository in your project's build.gradle:

allprojects {
    repositories {
        //...
        maven { url 'https://jitpack.io' }
    }
}

And then add the below to your app's build.gradle:

    implementation 'com.kroegerama:bottomsheet-imagepicker:<version>'

Step 1: Create your own FileProvider

Just follow the guide from Official Android Document. See the demo application file_paths.xml and AndroidManifest.xml.

Step 2: Implement the callback handler

The caller Activity or Fragment has to implement BottomSheetImagePicker.OnImagesSelectedListener to receive the selection callbacks. It will automatically be used by the image picker. No need to register a listener.

Kotlin
class AcMain: BaseActivity(), BottomSheetImagePicker.OnImagesSelectedListener {
    //...

    override fun onImagesSelected(uris: List<Uri>, tag: String?) {
        toast("Result from tag: $tag")

        imageContainer.removeAllViews()
        uris.forEach { uri ->
            val iv = LayoutInflater.from(this).inflate(R.layout.scrollitem_image, imageContainer, false) as ImageView
            imageContainer.addView(iv)
            Glide.with(this).load(uri).into(iv)
        }
    }
}
Java
public class AcMainJava extends BaseActivity implements BottomSheetImagePicker.OnImagesSelectedListener {
    //...
    
    @Override
    public void onImagesSelected(@NotNull List<? extends Uri> uris, @Nullable String tag) {
        imageContainer.removeAllViews();
        for (Uri uri : uris) {
            ImageView iv = (ImageView) LayoutInflater.from(this).inflate(R.layout.scrollitem_image, imageContainer, false);
            imageContainer.addView(iv);
            Glide.with(this).load(uri).into(iv);
        }
    }
}

You can set a requestTag in the builder. This is useful when you need to show more than one picker on the same page. You will receive this tag as tag parameter in the callback.

Step 3: Create the image picker using the Builder

The setters are all optional and the builder will fallback to default values.

single select

Kotlin
    BottomSheetImagePicker.Builder(getString(R.string.file_provider))
        .cameraButton(ButtonType.Button)            //style of the camera link (Button in header, Image tile, None)
        .galleryButton(ButtonType.Button)           //style of the gallery link
        .singleSelectTitle(R.string.pick_single)    //header text
        .peekHeight(R.dimen.peekHeight)             //peek height of the bottom sheet
        .columnSize(R.dimen.columnSize)             //size of the columns (will be changed a little to fit)
        .requestTag("single")                       //tag can be used if multiple pickers are used
        .show(supportFragmentManager)
Java
    new BottomSheetImagePicker.Builder(getString(R.string.file_provider))
       .cameraButton(ButtonType.Button)
       .galleryButton(ButtonType.Button)
       .singleSelectTitle(R.string.pick_single)
       .peekHeight(R.dimen.peekHeight)
       .columnSize(R.dimen.columnSize)
       .requestTag("single")
       .show(getSupportFragmentManager(), null);

multi select

Kotlin
    BottomSheetImagePicker.Builder(getString(R.string.file_provider))
        .multiSelect(3, 6)                  //user has to select 3 to 6 images
        .multiSelectTitles(
            R.plurals.pick_multi,           //"you have selected <count> images
            R.plurals.pick_multi_more,      //"You have to select <min-count> more images"
            R.string.pick_multi_limit       //"You cannot select more than <max> images"
        )
        .peekHeight(R.dimen.peekHeight)     //peek height of the bottom sheet
        .columnSize(R.dimen.columnSize)     //size of the columns (will be changed a little to fit)
        .requestTag("multi")                //tag can be used if multiple pickers are used
        .show(supportFragmentManager)
Java
    new BottomSheetImagePicker.Builder(getString(R.string.file_provider))
        .multiSelect(3, 6)
        .multiSelectTitles(
                R.plurals.pick_multi,
                R.plurals.pick_multi_more,
                R.string.pick_multi_limit
        )
        .peekHeight(R.dimen.peekHeight)
        .columnSize(R.dimen.columnSize)
        .requestTag("multi")
        .show(getSupportFragmentManager(), null);

The image picker works in activities and fragments

Kotlin
    //inside activity
        .show(supportFragmentManager)
    //inside fragment
        .show(childFragmentManager)
Java
    //inside activity
        .show(getSupportFragmentManager(), null);
    //inside fragment
        .show(getChildFragmentManager(), null);

bottomsheet-imagepicker's People

Contributors

kroegerama avatar suriyadi15 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bottomsheet-imagepicker's Issues

Can not use this in Fragment with kotlin

I have debugged and get to know that onCreateView is calling of bottomviewpicker but here

(parentFragment as? OnImagesSelectedListener)?.let { onImagesSelectedListener = it }

you initialize the onImagesSelectedListener but the parentFragment is null here due to which i am not getting any callback.

Can you help here please ??

Multiple images

Hello how are u? i need a help to display camera button in multiple selection can you help me how i can do it?

Camera option

Please add camera option in multi selection image and stop selection if maximum image select.

Question

Hello, you did a great job, but why you are using not stable com.google.android.material:material library. I see you are using 1.1.0-rc1 . In my project, I'm using 1.0.0 and this is cause problem for my custom BootomSheet Dialogs. Is it possible to change at least
api 'com.google.android.material:material:1.1.0-rc01' to =>
implementation 'com.google.android.material:material:1.1.0-rc01' I guess it will help hide the library and not mixed different versions.

multi selection

hello, thanks for your efforts. I am facing a problem when i set number of max images in multi select function, then user select images to defined length and send network request then it is showing toast msg of max length exceeded. please guide how can i figure it out.

Thank you.

[CRASH IllegalStateException] Fragment not attached to a context

Fatal Exception: java.lang.IllegalStateException: Fragment BottomSheetImagePicker{f018108 (68ca9b62-3687-46ba-8b5b-af03bbc42f90)} not attached to a context. at androidx.fragment.app.Fragment.requireContext(Fragment.java:774) at androidx.fragment.app.Fragment.getResources(Fragment.java:838) at com.kroegerama.imgpicker.BottomSheetImagePicker$onCreateDialog$$inlined$apply$lambda$1.onShow(BottomSheetImagePicker.kt:165) at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1595) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:237) at android.app.ActivityThread.main(ActivityThread.java:8016) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076)

Received this crash multiple times in my app in procuction
Device: Galaxy S10+ running android 10

Does anyone know what is the cause of this?

Camera not working in Android 10

Hi, the camera still is not working in Android 10, I think it is due to the scoped storage change in Android 10.
I debugged everything and the line which i giving the exception is:

BottomSheetImagePicker.kt Line 255:
val image = File.createTempFile(imageFileName, ".jpg", storageDir)

This is resulting in "Method threw 'java.io.IOException' exception."

Device is One Plus 6T

Changing the UI of the Picker

I wonder if I could change the UI of the image Picker without the needed of fork the project and modify the code.
Thanks a lot!

Can i selectively open only Internal storage or External Storage

There are times that i want to open images only from InternalStorage or other times only from ExternalStorage and other times both. How can i do that?
My fileProvider is

<paths>
    <files-path
        name="files"
        path="." />

    <external-files-path
        name="external_path_files"
        path="." />

    <external-path
        name="external_files"
        path="."/>
</paths>

Thank you

Android 13 Permissions Issue

Since Android 13 removed the storage permission, the BottomSheetImagePicker.Builder is no longer working because when it goes to BottomSeetImagePicker's onCreate, it goest into the else of the ReadStoragePermission has if it had no permission and get's stuck on a loop on PermissionUtils, because android 13 does not ask for that permission

Fatal Exception: android.os.FileUriExposedException

Fatal Exception: android.os.FileUriExposedException: file:///storage/emulated/0/DCIM/IMG_20200117_132719_5474483360980881045.jpg exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1978)
at android.net.Uri.checkFileUriExposed(Uri.java:2371)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:963)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10252)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10237)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1669)
at android.app.Activity.startActivityForResult(Activity.java:4651)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676)
at androidx.core.app.ActivityCompat.startActivityForResult(ActivityCompat.java:234)
at androidx.fragment.app.FragmentActivity.startActivityFromFragment(FragmentActivity.java:796)
at androidx.fragment.app.FragmentActivity$HostCallbacks.onStartActivityFromFragment(FragmentActivity.java:933)
at androidx.fragment.app.Fragment.startActivityForResult(Fragment.java:1206)
at androidx.fragment.app.Fragment.startActivityForResult(Fragment.java:1194)
at com.kroegerama.imgpicker.BottomSheetImagePicker.launchCamera(BottomSheetImagePicker.kt:243)
at com.kroegerama.imgpicker.BottomSheetImagePicker.access$launchCamera(BottomSheetImagePicker.kt:39)
at com.kroegerama.imgpicker.BottomSheetImagePicker$onViewCreated$3.onClick(BottomSheetImagePicker.kt:131)
at android.view.View.performClick(View.java:6615)
at android.view.View.performClickInternal(View.java:6592)
at android.view.View.access$3100(View.java:786)
at android.view.View$PerformClick.run(View.java:25951)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6815)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.