We’ve already discussed ViewPager
in depth in one of my earlier posts. We saw how to use it with specific PagerAdapter
implementations like FragmentPagerAdapter
and FragmentStatePagerAdapter
that works with fragments but we can also use it to inflate any other View
or ViewGroup
(with standard View hierarchy) by hooking it up with PagerAdapter
itself. In this tutorial we’ll just discuss how to how to hook a PagerAdapter
to a ViewPager
to create an Image slideshow.
Setting Up
Firstly, we’ll need to have a ViewPager
element in our layout file at res/layout/activity_main.xml
:
What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" android:id="@+id/relativeLayout"> <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v4.view.ViewPager> </RelativeLayout>
Next, in our onCreate()
Activity method, we’ll instantiate our custom PagerAdapter
implementation and bind it to our ViewPager
object.
mCustomPagerAdapter = new CustomPagerAdapter(this); mViewPager = (ViewPager) findViewById(R.id.pager); mViewPager.setAdapter(mCustomPagerAdapter);
In our Activity class we’ll have a mResources
instance variable that’ll contain an array of drawable resource IDs:
int[] mResources = { R.drawable.first, R.drawable.second, R.drawable.third, R.drawable.fourth, R.drawable.fifth, R.drawable.sixth };
I downloaded six images from LoremPixel of size 400×600 and put them into the res/drawable
directory. We’ll use these images in our carousel.
Finally it’s time to write our custom pager adapter implementation that’ll do the real job of populating content pages within our ViewPager
:
class CustomPagerAdapter extends PagerAdapter { Context mContext; LayoutInflater mLayoutInflater; public CustomPagerAdapter(Context context) { mContext = context; mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return mResources.length; } @Override public boolean isViewFromObject(View view, Object object) { return view == ((LinearLayout) object); } @Override public Object instantiateItem(ViewGroup container, int position) { View itemView = mLayoutInflater.inflate(R.layout.pager_item, container, false); ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView); imageView.setImageResource(mResources[position]); container.addView(itemView); return itemView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((LinearLayout) object); } }
Let’s discuss the four methods that we’ve overridden (mandatory):
-
getCount()
– This method should return the number of views available, i.e., number of pages to be displayed/created in theViewPager
. -
instantiateItem()
– This method should create the page for the givenposition
passed to it as an argument. In our case, weinflate()
our layout resource to create the hierarchy of view objects and then set resource for theImageView
in it. Finally, the inflated view is added to the container (which should be theViewPager
) and return it as well. -
destroyItem()
– Removes the page from the container for the given position. We simply removedobject
usingremoveView()
but could’ve also usedremoveViewAt()
by passing it theposition
. -
isViewFromObject()
– The object returned byinstantiateItem()
is a key/identifier. This method checks whether the View passed to it (representing the page) is associated with that key or not. It is required by aPagerAdapter
to function properly. For our example, the implementation of this method is really simple, we just compare the two instances and return the evaluated boolean.
Here’s how res/layout/pager_item.xml
will look like which is inflated in the instantiateItem()
method:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/imageView" /> </LinearLayout>
Now if you go and test your app in the emulator or a device, you’ll be able to play with a nice slideshow based on ViewPager
with 6 pages each showing up an image from the drawable resources directory.
It is important to understand that as the user navigates to a particular page, the one next to it is generated by calling instantiateItem()
while the one before the previous one gets destroyed by calling destroyItem()
. This caching limit (destruction and rebuilding limit) can be specified by the setOffscreenPageLimit()
method on the ViewPager
object which is set to 1 by default. Increasing this value to a higher number leads to a smoother navigation as far as the animations and interactions are concerned as everything is retained in memory but then it can also cause a memory overhead affecting the app’s performance. So you’ve to find the perfect balance in your case.
Hope that helps!
Hi,
Rishabh your article is good . I want to have this image slider inside my tab swipable view .
How can i implement that
I guess this is how you’re implementing Swipeable Views. So in that case one of your fragments will need to implement what you’re doing in this post.
This might lead to an issue though where you’ve a ViewPager inside another one hence which one should actually Swipe ? Although I haven’t tried doing this but you might want to understand the touch events system of Android to solve such issues. I’ve written a couple of related posts:
– http://codetheory.in/understanding-android-input-touch-events/
– http://codetheory.in/using-a-scrollable-viewgroup-in-a-scrollview/
Hope that helps!
Yes I tried but no changes in the image size, and i set scaleType = “fitXY” ,but i dint get an expected output, can u help me?
Excelent. Example of viewPage
Hey, its good article, i need bit help of you, can you tell me about videos slideshow, can i use viewpager for videos slide show.
Thanks
Have you tried the code in this article with a
VideoView
instead ofImageView
?Great tutorial! One question: wouldn’t it be better to call LayoutInflater.from(container.getContext()).inflate(…)? that way you don’t have to keep the Context or the Layout inflater around.
Is there any problem with keeping the LayoutInflater around ? I don’t think so. It’s just fine. Also this way you cache the layout inflater in a way rather than obtaining it every time by making a call to
from()
although it shouldn’t be much of a difference – see if this SO thread helps.Exactly what I was looking for . Nice work.
Hi , It was very useful..Thank you Rishabh, I am a beginer ,i want to display this slideshow in a tablet, i have changed the image size for that ,but still the image is smaller than screen size (width and height) how can i solve this issue?? help me please? i changed the height and width of image view as wrap_content
Did you try
fill_parent
ormatch_parent
instead ofwrap_content
for the image view ?Can yu help me ? I tried both fill_parent and match_parent
Thanks, I was a useful post, when I use this, on the left most page when I swipe it left to right I see a scroll shadow, but that is not covering up entire height of image view, how Can I remove this issue?
Great tutorial!!!! thanks a million, helped me alot one question though, how can i make viewer flip every seconds? thanks again
This should be of help – http://stackoverflow.com/a/17167920/2272910
is it possible to implement the same in normal activities?
Yes, I was using a “normal” Activity only.
Nothing is getting displayed. I followed all the instructions stated in the post.Please help.
Hey man! great tutorial exactly what I was looking for! I’ve only got one question…can you tell me what to add in order to display full hd pictures? I tried loading a scaled down version of the image as the official site suggested (http://developer.android.com/training/displaying-bitmaps/load-bitmap.html) but whenever i swipe from the one image to the other my app skips frames…do you have any idea how to solve my problem?
Hi! I would like to ask about mResources. My pictures in DB. How can I get id of these pictures?
I have similar problem and I cant find solution for days. Have you solve it?
Also I m having same problem, Can anybody help me how I can fix this.
hey can you help me ?
I am getting an error on above code at ‘mResources’. Where to initialized it ?
I’ve initialized it in the code if you notice.
Fail! It did not work for me
i am trying your code but mResource variable is not resolved.
I declared mResource[] array in main class placed in one package and CustomPageAdapter placed in another package.
@Override
public int getCount() {
return mResources.length;
}
length is a function not a field.
Nice post bro, but I thought posting some pictures along with the code would be perfect touch to the posts.
Hi Rishabh,
I am following your code. Every time getting outof memory exception.
Please give some input.
you should update layout View pager code
Everything else is fine
thansk
Thanks Rishabh ! You really saved my day 🙂
Thanks Rishabn! It’s easy to follow. We have developed a new a unique transition between slides: https://github.com/Cleveroad/Bitutorial. Could you give your opinion, please?
Dear Rishabh,
very nice tutorial. It worked for me like a charm.
Now, I want to make this slider automatic (continuous run) so can you please help me with this.
Please mention in the solution where to put the new code (automatic slide).
Regards,
Mayur
Carousel of images with the total of 5 images. I want to swipe them to left or right side with the sound of kat kat kat. How to do it, man. Please tell me that
Hey Rishabh! please help me here..
I am creating a college project app in which I am using vertical layout for vertical orientation and horizontal layout for horizontal orientation,it has a viewpager for image sliding,which has also two layouts i.e. vertical and horizontal.It is working fine with vertical but when I changes the oreintation to landscape,the viewpager’s horizontal layout doesn’t inflates. Please help me in resolving my problem.Thank you