ScrollGalleryView is a flexible library which helps you to create awesome media galleries in your Android application.

Overview

ScrollGalleryView

Build Status Android Arsenal Join the chat at https://gitter.im/VEINHORN/ScrollGalleryView

ScrollGalleryView is a flexible library which helps you to create awesome media galleries in your Android application. It's easily integrated with the most popular image loading libraries such as Picasso, Glide and Fresco.

ScrollGalleryView

Key features

  • Easy way to select images in gallery (thumbnails)
  • Zooming
  • Simple API
  • Video

Installing

Add JitPack repository to your root build.gradle (see more details here):

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

Add dependency to your module build.gradle:

implementation 'com.veinhorn.scrollgalleryview:library:1.2.6'

MediaLoaders

There are several MediaLoaders implementations for most popular caching libraries: Picasso, Glide, Fresco.

Picasso

implementation 'com.veinhorn.scrollgalleryview:picasso-loader:1.2.4'

Glide

implementation 'com.veinhorn.scrollgalleryview:glide-loader:1.2.9'

Fresco

implementation 'com.veinhorn.scrollgalleryview:fresco-loader:1.2.4'

Usage

Add ScrollGalleryView to your layout:

">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.veinhorn.scrollgalleryview.ScrollGalleryView
        android:id="@+id/scroll_gallery_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000"/>
LinearLayout>

Initialize ScrollGalleryView in your activity:

import static com.veinhorn.scrollgalleryview.loader.picasso.dsl.DSL.*; // simplifies adding media

public class MainActivity extends FragmentActivity {
    private ScrollGalleryView galleryView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        galleryView = ScrollGalleryView
                .from((ScrollGalleryView) findViewById(R.id.scroll_gallery_view))
                .settings(
                        GallerySettings
                                .from(getSupportFragmentManager())
                                .thumbnailSize(100)
                                .enableZoom(true)
                                .build()
                )
                .add(image("http://pirate-islands.com/wp-content/uploads/2018/07/07_Dom-Fernando-II_01-636x310.jpg"))
                .add(image("http://povodu.ru/wp-content/uploads/2016/04/pochemu-korabl-derzitsa-na-vode.jpg"))
                .add(video("http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4", R.mipmap.default_video))
                .build();
    }
}

If you use ScrollGalleryView version prior 1.2.0 or need more info about gallery initialization you can find it here.

Adding media

ScrollGalleryView supports different types of media such as images and videos. You can create image gallery, video gallery, or mix them in any way. To abstract from concreate way of image loading ScrollGalleryView uses MediaLoader so it makes possible to use different image loading libraries depending on your needs (Picasso, Glide, Fresco).

Picasso loader

Default image loader

Library is also contains default image loader but it's not optimized for performance.

Note: it's highly recommended to use custom image loader against default

Configuration

You can specify a bunch of additional settings during gallery initialization.

Option Method Description
Thumbnail size .setThumbnailSize(200) You can configure thumbnails size in
Zoom .setZoom(true) Enable zoom
Hide thumbnails .withHiddenThumbnails(false) Hide scroll view container with thumbnails on the bottom of screen
Hide thumbnails on click .hideThumbnailsOnClick(true) Hide scroll view container with thumbnails when you click on main image area

Adding listeners

ScrollGalleryView supports adding listeners for events like: image click, long image click, changed page. More details you can find in separate doc.

Sample application

The sample application published on Google Play.

Get it on Google Play

License

MIT License

Copyright (c) 2019 Boris Korogvich

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Comments
  • Failed to resolve

    Failed to resolve

    I've got the same issue as #68 (closed): "failed to resolve com.github.chrisbanes:PhotoView:2.0.0"

    What was/is the solution for this problem?

    opened by Bernhardino 9
  • Error scrollGalleryView.setOnScrollChangeListener

    Error scrollGalleryView.setOnScrollChangeListener

    I got error when I add this code :(

     scrollGalleryView.setOnScrollChangeListener(new OnScrollChangeListener() {
      @Override
      public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
    
      }
     });
    
    opened by firestork 8
  • why place holder doesnt remove

    why place holder doesnt remove

    Why what ever i do my first position is place holder icon?!

    screenshot_1523283813

    And this is my code:

     ArrayList<String> strings = new ArrayList<>();
    
            strings.add("http://img1.goodfon.ru/original/1920x1080/d/f5/aircraft-jet-su-47-berkut.jpg");
            strings.add("http://img1.goodfon.ru/original/1920x1080/d/f5/aircraft-jet-su-47-berkut.jpg");
            strings.add("http://img1.goodfon.ru/original/1920x1080/d/f5/aircraft-jet-su-47-berkut.jpg");
    
            List<MediaInfo> infos = new ArrayList<>(strings.size());
            for (String url : strings) infos.add(MediaInfo.mediaLoader(new PicassoImageLoader(url)));
    
            scrollGalleryView = findViewById(R.id.scroll_gallery_view);
            scrollGalleryView
                    .setThumbnailSize(200)
                    .setZoom(true)
                    .setFragmentManager(getSupportFragmentManager())
                    .addMedia(MediaInfo.mediaLoader(new MediaLoader() {
                        @Override public boolean isImage() {
                            return true;
                        }
    
                        @Override public void loadMedia(Context context, ImageView imageView,
                                                        MediaLoader.SuccessCallback callback) {
                            callback.onSuccess();
                        }
    
                        @Override public void loadThumbnail(Context context, ImageView thumbnailView,
                                                            MediaLoader.SuccessCallback callback) {
                            callback.onSuccess();
                        }
                    }))
                    .addMedia(infos);
        }
    

    And for PicassoImageLoader:

    public class PicassoImageLoader implements MediaLoader {
        private String url;
        private Integer thumbnailWidth;
        private Integer thumbnailHeight;
    
        public PicassoImageLoader(String url) {
            this.url = url;
        }
    
        public PicassoImageLoader(String url, Integer thumbnailWidth, Integer thumbnailHeight) {
            this.url = url;
            this.thumbnailWidth = thumbnailWidth;
            this.thumbnailHeight = thumbnailHeight;
        }
    
        @Override
        public boolean isImage() {
            return true;
        }
    
        @Override
        public void loadMedia(Context context, final ImageView imageView, final MediaLoader.SuccessCallback callback) {
            Picasso.get()
                    .load(url)
                    .into(imageView, new ImageCallback(callback));
        }
    
        @Override
        public void loadThumbnail(Context context, final ImageView thumbnailView, final MediaLoader.SuccessCallback callback) {
            Picasso.get()
                    .load(url)
                    .resize(thumbnailWidth == null ? 300 : thumbnailWidth,
                            thumbnailHeight == null ? 300 : thumbnailHeight)
                     .centerInside()
    
                    .into(thumbnailView, new ImageCallback(callback));
        }
    
        private static class ImageCallback implements Callback {
            private final MediaLoader.SuccessCallback callback;
    
            public ImageCallback(SuccessCallback callback) {
                this.callback = callback;
            }
    
            @Override
            public void onSuccess() {
                callback.onSuccess();
            }
    
            @Override
            public void onError(Exception e) {
    
            }
    
    
        }
    
    opened by amirhrezf 7
  • Image fails to re-load after rotate

    Image fails to re-load after rotate

    Seems the mediaLoader callback is never called, but the one on the thumbs is.

    End result is after rotation the thumbs are fine but the full images just remain place-holded.

    bug 
    opened by StainlessStlRat 4
  • OutOfMemory exception

    OutOfMemory exception

    java.lang.OutOfMemoryError: Failed to allocate a 46656012 byte allocation with 16771776 free bytes and 31MB until OOM
        at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
        at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
        at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
        at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
        at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080)
        at android.content.res.Resources.loadDrawableForCookie(Resources.java:2635)
        at android.content.res.Resources.loadDrawable(Resources.java:2540)
        at android.content.res.Resources.getDrawable(Resources.java:806)
        at android.content.res.Resources.getDrawable(Resources.java:771)
        at com.veinhorn.scrollgalleryview.loader.DefaultImageLoader.loadBitmap(DefaultImageLoader.java:48)
        at com.veinhorn.scrollgalleryview.loader.DefaultImageLoader.loadThumbnail(DefaultImageLoader.java:39)
        at com.veinhorn.scrollgalleryview.ScrollGalleryView.addMedia(ScrollGalleryView.java:101)
        at com.veinhorn.scrollgalleryview.ScrollGalleryView.addMedia(ScrollGalleryView.java:89)
        at com.veinhorn.example.MainActivity.onCreate(MainActivity.java:56)
        at android.app.Activity.performCreate(Activity.java:6251)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
        at android.app.ActivityThread.-wrap15(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    
    bug 
    opened by VEINHORN 4
  • Abstract image loading

    Abstract image loading

    Hello there, great lib!

    What first came to my mind is that loading the image could be abstracted away through an interface, so that client code can use whatever technique it wants (popular libraries like Picasso, Glide, Universal Image Loader, Fresco, etc.) instead of directly loading a Bitmap.

    So rather than using addImage(Bitmap image), it would be addImage(ScrollGalleryViewItem item), where:

    interface ScrollGalleryViewItem {
        View getView();
        View getThumbnail(int thumbnailSize);
    }
    

    (Just a rough sketch, but you get the idea)

    Also, there would be a default implementation of this interface SimpleScrollGalleryViewItem, which simply does what the lib currently does, so that people can easily use the lib without any extra code right away.

    What do you think?

    Ps.: :+1: for the nice, clean code :)

    opened by zsoltk 4
  • TransactionTooLargeException on Nougat

    TransactionTooLargeException on Nougat

    When open images and collapse app, show error. This maybe in ImageFragment in onSaveInstanceState method when call outState.putParcelable("image", ((BitmapDrawable)this.backgroundImage.getDrawable()).getBitmap());

    opened by agaDeonix 3
  • Add getCurrentItem method to ScrollGalleryView

    Add getCurrentItem method to ScrollGalleryView

    This is the simplest version of the change. I've just added getCurrentItem() that exposes the same method from ViewPager.

    I just noticed that you've added a getViewPager() method where you can get the whole ViewPager object. Maybe this could lead to bad usages from library users, such as changing the adapter and breaking up the whole thing.

    Anyway, if you want to include this method in the next version, I think it could be useful :) I wait for the next release to have some issues like #27 or #32 fixed.

    I've also had a look at #43. I think it is related to this code:

    public ScrollGalleryView setCurrentItem(int i) {
        viewPager.setCurrentItem(i, false);
        return this;
    }
    

    I've just discovered that setCurrentItem can be called before initializing the ViewPager, so it causes NullPointerException. A workaround could be calling .setCurrentItem after .setFragmentManager. I'll update my comment in #43.

    opened by voghDev 3
  • add OnPageChangeListener to ScrollGalleryView

    add OnPageChangeListener to ScrollGalleryView

    public class ScrollGalleryView extends LinearLayout {
     ...
      public void addOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
            viewPager.addOnPageChangeListener(listener);
      }
    ...
    
    opened by alexodus 3
  • please update glide, picasso and fresco libs

    please update glide, picasso and fresco libs

    Hi, Please update image loader libs to latest versions:

    //fresco version in fresco-loader:
    implementation 'com.facebook.fresco:fresco:1.11.0'
    //latest version is:
    implementation 'com.facebook.fresco:fresco:2.0.0'
    
    //glide version in glide-loader:
    implementation 'com.github.bumptech.glide:glide:4.8.0'
    //latest version is:
    implementation 'com.github.bumptech.glide:glide:4.9.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
    
    //glide version in picasso-loader:
    implementation 'com.squareup.picasso:picasso:2.5.2'
    //latest version is:
    implementation 'com.squareup.picasso:picasso:2.71828'
    
    opened by mojtaba-yekta 2
  • Remove app name from library resources

    Remove app name from library resources

    I think it's better to remove resources such as app_name from the library, because it can cause clashes with app's own app_name resource. If someone uses app_name resource value (especially in layout, which was in my case), he will see ScrollGalleryView instead of his own app name.

    Library has two res files which contains app_name string: ScrollGalleryView/library/src/main/res/values-ru/strings.xml ScrollGalleryView/library/src/main/res/values/strings.xml

    opened by trupizzza 2
  • fixed setCurrentItem method to also adjust the thumbnails

    fixed setCurrentItem method to also adjust the thumbnails

    The original setCurrentItem method only adjusted the main image and the thumbnails always started with the first one. I added a scroll(thumbnailsContainer.getChildAt(i)) and attached it to the lifecycle of the main view so it would be executed after the main view was built.

    opened by MaAllma 0
  • crash

    crash

    Unable to start activity java.lang.IllegalArgumentException: width and height must be > 0

    val galleryView = ScrollGalleryView.from(findViewById(R.id.galleryView))
                .settings(GallerySettings.from(supportFragmentManager).enableZoom(true).build())
                .add(medias)
                .build()
    
    opened by pmrzygweb 1
  • setCurrentItem does not adjust the thumbnails

    setCurrentItem does not adjust the thumbnails

    I want to start my Image Gallery by clicking on a specific photo. For this I use the setCurrentItem method. This works perfect for the main image, but the thumbnails still start with the first image and not the selected one. Is there an interface for this that I've overseen, or can setCurrentItem be changed so that the thumbnails are also adjusted in it? ( scroll(thumbnailsContainer.getChildAt(i)) ) thanks :)

    opened by MaAllma 0
  • No virtual method placeholder

    No virtual method placeholder

    E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.dragtest, PID: 12168 java.lang.NoSuchMethodError: No virtual method placeholder(I)Lcom/bumptech/glide/request/RequestOptions; in class Lcom/bumptech/glide/request/RequestOptions; or its super classes (declaration of 'com.bumptech.glide.request.RequestOptions' appears in /data/data/com.example.dragtest/code_cache/.overlay/base.apk/classes.dex) at ogbe.ozioma.com.glideimageloader.GlideImageLoader.(GlideImageLoader.java:26) at ogbe.ozioma.com.glideimageloader.GlideMediaHelper.image(GlideMediaHelper.java:13) at ogbe.ozioma.com.glideimageloader.dsl.DSL.image(DSL.java:13) at com.example.unipic.views.activities.ImageActivity.initImageActivity(ImageActivity.kt:73) at com.example.unipic.views.activities.ImageActivity.onCreate(ImageActivity.kt:43) at android.app.Activity.performCreate(Activity.java:8198) at android.app.Activity.performCreate(Activity.java:8182) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3765) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3968) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8506) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

    opened by Jetug 2
  • JCenter is shutting down: migrate to Maven Central

    JCenter is shutting down: migrate to Maven Central

    Please upload the library to Maven Central. Jcenter is shutting down.

    Roughly there are two things that will need to be done:

    1. Change publishing pipeline to upload new library versions to Maven Central
    2. Migrate all existing artifacts to Maven Central.

    From: https://jeroenmols.com/blog/2021/02/04/migratingjcenter/ More info: https://proandroiddev.com/publishing-your-first-android-library-to-mavencentral-be2c51330b88

    opened by Frank1234 3
  • Make Scroll Gallery View Dynamically -> here is the answer

    Make Scroll Gallery View Dynamically -> here is the answer

    List<MediaInfo> dynamicMediaList= new ArrayList<>();
    
    for (String path : imagePath){
    
          dynamicMediaList.add(MediaInfo.mediaLoader(new PicassoImageLoader(path)));
    
    }
    
    ScrollGalleryView.from(findViewById(R.id.scroll_gallery_view))
                   .settings(
                            GallerySettings
                                    .from(getSupportFragmentManager())
                                    .thumbnailSize(200)
                                    .enableZoom(true)
                                    .build()
                    )
                    .add(dynamicMediaList)
                    .build();
    
    opened by mrnirva 2
Releases(v1.2.7)
Owner
Boris Korogvich
I'm a inquisitive software developer with a keen interest in Java/Scala/Python.
Boris Korogvich
A cross-platform mobile app that helps you to generate transcripts either from a voice recording or by uploading an audio file

A cross-platform mobile app that helps you to generate transcripts either from a voice recording or by uploading an audio file

Souvik Biswas 26 Dec 18, 2022
Social media for super cool developers πŸ§‘πŸΎβ€πŸ’»πŸ‘‹πŸ½

Develove ????‍?? Demo link: Develove App release: Develove.apk Develove is a super cool social media forum that aims to bring in the best features of

Luxecraft 21 Dec 9, 2022
A Flutter package for both android and iOS which provides Audio recorder

social_media_recorder A Flutter package for both android and iOS which provides

subhikhalifeh 16 Dec 29, 2022
Flutter plugin for selecting multiple images from the Android and iOS image library

Flutter plugin for selecting multiple images from the Android and iOS image library, taking new pictures with the camera, and edit them before using such as rotating, cropping, adding sticker/filters.

Weta Vietnam 91 Dec 19, 2022
Create responsive music design using Flutter

Create responsive music design using Flutter

Firgia 40 Dec 27, 2022
WaVe - an audio streaming platform which gives the best user experience without any compromise in the audio quality

WaVe is an audio streaming platform which gives the best user experience without any compromise in the audio quality, and there is even space for the users to explore their creativity. And makes it more efficient with the AI features.

OmarFayadhd 1 May 31, 2022
Music Player app made with Just audio library and Local database Hive.

Music Player app made with Just audio library and Local database Hive. Find the free and Royelty music with Happy Rock application. The app contains information about singers and you can make your own playlist with Songs.Happy rock App's features are same as the real music app like spotify, amazon music etc.

Ansh rathod 17 Dec 22, 2022
Playify is a Flutter plugin for play/pause/seek songs, fetching music metadata, and browsing music library.

Playify Playify is a Flutter plugin for play/pause/seek songs, fetching music metadata, and browsing music library. Playify was built using iOS's Medi

Ibrahim Berat Kaya 32 Dec 14, 2022
Image Extensions A wrapper library for image package with some extra functions.

A wrapper library for image package with some extra functions. Installation Add this to your package's pubspec.yaml file: dependencie

Vanxh 1 Jan 15, 2022
You can play various sounds using this app

Xylophone ?? Our Goal In this tutorial we will be diving into more Dart programming concepts and learning how to use open source Flutter packages. By

Kuldeep Rathor 1 Oct 23, 2021
Flutter-Music-Player - A simple music player app that let you play mp3 songs with some customization feature with a rich user interface

Flutter-Music-Player - A simple music player app that let you play mp3 songs with some customization feature with a rich user interface

Ashirbad Swain 6 Jan 4, 2023
A Flutter project thats shows you how to upload, view and delete images using firebase cloud storage

firebase_image_upload A Flutter project thats shows you how to upload, view and

null 4 Nov 21, 2022
Official Flutter SDK for LiveKit. Easily add real-time video and audio to your Flutter apps.

LiveKit Flutter SDK Official Flutter SDK for LiveKit. Easily add real-time video and audio to your Flutter apps. This package is published to pub.dev

LiveKit 116 Dec 14, 2022
Keep tracking your prayers

Keep tracking your prayers

Hasan Ragab Eltantawy 24 Dec 30, 2022
Use your Flutter knowledge to generate videos, animations and slideshows

Use your Flutter knowledge to generate videos, animations and slideshows! Automate your video production with server-side rendering. Footage is still

AloΓ―s Deniel 131 Dec 7, 2022
Play simultaneously music/audio from assets/network/file directly from Flutter, compatible with android / ios / web / macos, displays notifications

?? assets_audio_player ?? Play music/audio stored in assets files (simultaneously) directly from Flutter (android / ios / web / macos). You can also u

Florent CHAMPIGNY 651 Dec 24, 2022
A flutter plugin to handle Android / iOS camera

?? Overview Flutter plugin to add Camera support inside your project. CamerAwesome include a lot of useful features like: ?? Live camera flip ( switch

Apparence.io 511 Jan 5, 2023
A Flutter plugin to use speech recognition on iOS & Android (Swift/Java)

speech_recognition A flutter plugin to use the speech recognition iOS10+ / Android 4.1+ Basic Example Sytody, speech to todo app Installation Depend o

Erick Ghaumez 331 Dec 19, 2022