Yuriy Kolbasinskiy
Yuriy Kolbasinskiy

Reputation: 3841

Android Horizontal scrolling image gallery

I'd like to create app with horizontal image gallery (with one row and multiple columns). First i try to use gridview, but it can be used as vertical scroll only. Can i use ListView or GridView for that purposes?

Image gallery with horizontal scrolling

Upvotes: 20

Views: 61069

Answers (5)

Kamo
Kamo

Reputation: 242

Since we no longer have the Gallery widget a bit of DIY nouse is required. You can create a horizontally scrolling thumbnail strip with a HorizontalScrollView and a nested LinearLayout, and dynamically add images to it from within your activity:

<HorizontalScrollView
    android:layout_width="match_parent"
    android:layout_height="72dp"
    android:layout_gravity="bottom"
    android:background="@color/black">
    <LinearLayout
        android:id="@+id/thumbnails"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:paddingTop="2dp"/>
</HorizontalScrollView>

The code below is taken from this tutorial: http://sourcey.com/android-horizontally-scrolling-pan-scan-and-zoom-image-gallery/ The GalleryActivity implements what you're looking for, and also expands on your request by adding a ViewPager element for showing the selected image, and a SubsamplingScaleImageView so you can pan, scan and zoom the selected image:

package com.sourcey.imagegallerydemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v7.app.AppCompatActivity;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.davemorrissey.labs.subscaleview.ImageSource;
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;

import junit.framework.Assert;

import java.util.ArrayList;

import butterknife.ButterKnife;
import butterknife.InjectView;

public class GalleryActivity extends AppCompatActivity {
    public static final String TAG = "GalleryActivity";
    public static final String EXTRA_NAME = "images";

    private ArrayList<String> _images;
    private GalleryPagerAdapter _adapter;

    @InjectView(R.id.pager) ViewPager _pager;
    @InjectView(R.id.thumbnails) LinearLayout _thumbnails;
    @InjectView(R.id.btn_close) ImageButton _closeButton;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gallery);
        ButterKnife.inject(this);

        _images = (ArrayList<String>) getIntent().getSerializableExtra(EXTRA_NAME);
        Assert.assertNotNull(_images);

        _adapter = new GalleryPagerAdapter(this);
        _pager.setAdapter(_adapter);
        _pager.setOffscreenPageLimit(6); // how many images to load into memory

        _closeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "Close clicked");
                finish();
            }
        });
    }

    class GalleryPagerAdapter extends PagerAdapter {

        Context _context;
        LayoutInflater _inflater;

        public GalleryPagerAdapter(Context context) {
            _context = context;
            _inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            return _images.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == ((LinearLayout) object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, final int position) {
            View itemView = _inflater.inflate(R.layout.pager_gallery_item, container, false);
            container.addView(itemView);

            // Get the border size to show around each image
            int borderSize = _thumbnails.getPaddingTop();

            // Get the size of the actual thumbnail image
            int thumbnailSize = ((FrameLayout.LayoutParams)
                    _pager.getLayoutParams()).bottomMargin - (borderSize*2);

            // Set the thumbnail layout parameters. Adjust as required
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(thumbnailSize, thumbnailSize);
            params.setMargins(0, 0, borderSize, 0);

            // You could also set like so to remove borders
            //ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
            //        ViewGroup.LayoutParams.WRAP_CONTENT,
            //        ViewGroup.LayoutParams.WRAP_CONTENT);

            final ImageView thumbView = new ImageView(_context);
            thumbView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            thumbView.setLayoutParams(params);
            thumbView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d(TAG, "Thumbnail clicked");

                    // Set the pager position when thumbnail clicked
                    _pager.setCurrentItem(position);
                }
            });
            _thumbnails.addView(thumbView);

            final SubsamplingScaleImageView imageView =
                    (SubsamplingScaleImageView) itemView.findViewById(R.id.image);

            // Asynchronously load the image and set the thumbnail and pager view
            Glide.with(_context)
                    .load(_images.get(position))
                    .asBitmap()
                    .into(new SimpleTarget<Bitmap>() {
                        @Override
                        public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
                            imageView.setImage(ImageSource.bitmap(bitmap));
                            thumbView.setImageBitmap(bitmap);
                        }
                    });

            return itemView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((LinearLayout) object);
        }
    }
}

The full Android project is up on Github: https://github.com/sourcey/imagegallerydemo

Please select an answer if you have what you're looking for...

Upvotes: 0

Saritha
Saritha

Reputation: 488

create LinearLayout inside HorizontalScrollView,then create an imageView dynamically and add that imageview to linearLayout.

Example code:

<HorizontalScrollView 
android:id="@+id/horizontal_scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content" >

    <LinearLayout
    android:id="@+id/linear"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >
    </LinearLayout>

</HorizontalScrollView>

In onCreate() method,get the id of linearLayout from the xml file and add dynamically created ImageView to linearlayout:

    LinearLayout layout = (LinearLayout) findViewById(R.id.linear);
    for (int i = 0; i < 10; i++) {
        ImageView imageView = new ImageView(this);
        imageView.setId(i);
        imageView.setPadding(2, 2, 2, 2);
        imageView.setImageBitmap(BitmapFactory.decodeResource(
                getResources(), R.drawable.ic_launcher));
        imageView.setScaleType(ScaleType.FIT_XY);
        layout.addView(imageView);
    }

Upvotes: 32

Mark
Mark

Reputation: 525

HorizontalScrollView Documentation

To use HorizontalScrollView you should only have one child inside it. The way I have used it before with images like what you are doing is by creating a TableLayout and adding the images to the TableRows. The TableLayout can have many rows or just 1 row and many columns.

You can add ImageViews (or any other view) to each row and then you finally add the TableRow to the TableLayout. Once the TableLayout is made, all you need to do is:

    //createTable method is where you would loop through the images to add
    TableLayout table = createTable(rowCount, columnCount);
    HorizontalScrollView hozView = new HorizontalScrollView(this);
    hozView.addView(table);
    setContentView(hozView);

Upvotes: 0

belen
belen

Reputation: 193

TwoWayView worked good for me. https://github.com/lucasr/twoway-view/

Upvotes: 0

Anil Meenugu
Anil Meenugu

Reputation: 1431

Go with HorizontalScrollView instead of ListView or GirdView http://developer.android.com/reference/android/widget/HorizontalScrollView.html

Upvotes: 0

Related Questions