I'm currently working on showing the user an image gallery in my activity. This image gallery has to show an image with a preview left and right. Also I have to be able to put in images that have a portrait or landscape orientation.
I've done some research on this and found three ways of doing this.
Option 1: Viewpager
The viewpager seems easy to implement and with the negative margin in the: viewpager.setPageMargin(int)
method I can achieve the preview of the left and right images.
Issue
I can't seem to set the individual width of my views so that I don't have giant white spaces between my images when I have two portrait images next to each other in the ViewPager.
Option 2: HorizontalScrollView
Great component. Love the scrollbar at the bottom on my phone. Shows the user how many images are in the gallery when properly implemented.
Issue
I have to write the snapping logic myself. There are some examples out there which give me the snapping logic, but none have implemented anything with a preview of the previous and next image. Now I can invest quite some time into this, but that's not what I'm looking forward to doing.
Option 3: HorizontalPager
I like the simplicity of the view and that I can just push my ImageViews to this component, however how fast will this component stay when it has to handle more than a few ImageViews?
Issue
When adding padding between the ImageViews the HorizontalPager lags. The offset is also incorrect when using padding or margins.
The last two seem to use the MeasuredWidth's of the ImageViews and I wonder if they include the padding or margins. Either way, what seems to be the best solution to you guys and what could be modified the easiest?
Do you guys have any experience with this?
Thanks for the help.
I finally figured out how I wanted it. I finally succeeded in doing this while using a ViewPager:
GalleryAdapter:
public class GalleryAdapter extends PagerAdapter {
/**
* The collection of images contained in the view pager.
*/
public Integer[] mImages;
private InternalDatabase dbhelper;
private RuntimeExceptionDao<GalleryImage, Integer> imagesDao;
/**
* Constructor for the adapter. Initializes the images needed.
*/
public GalleryAdapter(Context context, Integer[] galleryImages) {
dbhelper = OpenHelperManager.getHelper(context, InternalDatabase.class);
imagesDao = dbhelper.getRuntimeExceptionDao(GalleryImage.class);
// TODO: create the proper collection to be able to display the images in the collection.
mImages = galleryImages;
}
@Override
public int getCount() {
if (mImages != null) {
if (mImages.length > 0) {
return mImages.length;
}
}
return 0;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((ImageView) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// Get the context from which the adapter is created.
// Need the context to create new views.
Context context = container.getContext();
// Create a new image view that will contain the image.
ImageView imageView = new ImageView(context);
LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
imageView.setLayoutParams(params);
// Scaling the image inside the wrapping view pager.
//imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
// Setting the image.
if (mImages != null) {
if (mImages.length > 0) {
Integer id = mImages[position];
GalleryImage image = imagesDao.queryForId(id);
Bitmap decodedByte = BitmapFactory.decodeByteArray(image.getImage(), 0, image.getImage().length);
imageView.setImageBitmap(decodedByte);
}
}
// Add the image to the view pager.
((ViewPager) container).addView(imageView);
return imageView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((ImageView) object);
}
}
LinearLayout view:
public class CardMiniatureGallery extends AbstractCompoundLinearLayout {
/**
* The viewpager that is used as a miniature gallery.
*/
public ViewPager mGallery;
private Integer[] mIDs;
public CardMiniatureGallery(Context context) {
super(context);
}
public CardMiniatureGallery(Context context, Integer[] images) {
super(context);
mIDs = images;
createLayout(context, mIDs);
}
public CardMiniatureGallery(Context context, AttributeSet attrs) {
super(context, attrs);
createLayout(context, mIDs);
}
public CardMiniatureGallery(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
createLayout(context, mIDs);
}
protected void createLayout(Context context) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.card_miniature_gallery, this, true);
}
private void createLayout(Context context, Integer[] ids) {
mGallery = (ViewPager) getChildAt(0);
GalleryAdapter adapter = new GalleryAdapter(context, mIDs);
mGallery.setAdapter(adapter);
mGallery.setOffscreenPageLimit(adapter.getCount());
mGallery.setClipToPadding(false);
int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 43, getResources().getDisplayMetrics());
mGallery.setPageMargin(margin);
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="250dp"
android:overScrollMode="never"
android:paddingLeft="85dp"
android:paddingRight="85dp"
android:layout_marginBottom="@dimen/padding_medium" />
With these classes and an array of Integers which I use to fetch the data from the database, I can display the images as I want. Now I only have to figure out how to dynamically set the ViewPager height by looking at the images it has to load.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments