Reputation: 3841
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?
Upvotes: 20
Views: 61069
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
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
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
Reputation: 193
TwoWayView worked good for me. https://github.com/lucasr/twoway-view/
Upvotes: 0
Reputation: 1431
Go with HorizontalScrollView instead of ListView or GirdView http://developer.android.com/reference/android/widget/HorizontalScrollView.html
Upvotes: 0