ViewPager with previous and next page boundaries
Solution 1
Quoting myself from a blog post on this subject:
The third approach comes from Dave Smith, co-author of the well-regarded book Android Recipes. He went in a very different direction, using a custom container that disabled children clipping to show more than one page at a time.
His published sample code shows the whole thing in action. His container (
com.example.pagercontainer.PagerContainer
) wraps theViewPager
and callssetClipChildren(false);
on itself, so even though theViewPager
is focused on one selected page, other pages that have coordinates beyond theViewPager
bounds are still visible, so long as they fit within thePagerContainer
. By sizing theViewPager
to be smaller than thePagerContainer
, theViewPager
can size its pages to that size, leaving room for other pages to be seen.PagerContainer
, though, needs to help out a bit with touch events, asViewPager
will only handle swipe events on its own visible bounds, ignoring any pages visible to the sides.
Solution 2
I have a similar solution:
On the viewpager set left and right padding, e.g. 20dp. Do also set the page margin on the viewpager, e.g. half of the pager padding. And do not forget to disable clip padding.
tilePager.setPadding(defaultGap, 0, defaultGap, 0);
tilePager.setClipToPadding(false);
tilePager.setPageMargin(halfGap);
Solution 3
-
Set left and right padding for whole item view. Example xml (page_item.xml):
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingLeft="20dp" android:paddingRight="20dp"/> <TextView android:id="@+id/text1" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout>
-
Then set negative page margin for
PageView
equal to 2*(previous view padding)int margin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20*2, getResources().getDisplayMetrics()); mViewPager.setPageMargin(-margin);
Optional. Set zero left padding for first item and zero right padding to last item to hide empty edges. You may do this in the
PageAdapter
orPage
fragment class.
Solution 4
To show preview of left and right pages set the following two values
viewpager.setClipToPadding(false)
viewpager.setPadding(left,0,right,0)
If you need space between two pages in the viewpager then add viewpager.setPageMargin(int)
Android ViewPager - Show preview of page on left and right
Solution 5
if someone still looking for solution, I had customized the ViewPage to achieve it without using negative margin, find a sample project here https://github.com/44kksharma/Android-ViewPager-Carousel-UI
it should work in most cases but you can still define page margin with
mPager.setPageMargin(margin in pixel);
Related videos on Youtube
![Gaurav Arora](https://i.stack.imgur.com/U6MWa.jpg?s=256&g=1)
Gaurav Arora
Speaks Android & React Native. LinkedIn: https://www.linkedin.com/in/gauravsapiens Medium: https://medium.com/@gauravsapiens
Updated on July 08, 2022Comments
-
Gaurav Arora almost 2 years
I'm designing a view with multiple pages. I want edges of previous and next pages to be show like below and implement a 2 finger swipe to switch between pages.
I tried using
ViewPager
with negative page margin as suggested here but that only shows one of the edges on the screen, not both simultaneously.Alternatively, is there any way i can position part of my view outside screen and then animate it giving it a
ViewPager
type effect.How should I go about it ? Thanks !
-
logray over 11 years"only shows one of the edges on the screen, not both simultaneously." Are you on page 0 and you only see part of page 1? Perhaps you need to use a circular pager, example and then set your page always to the "middle" position. See this post and the comment : stackoverflow.com/a/8304474/1851478
-
-
Shruti about 11 yearsby using this,I am able to show part of previous and next page as shown in image above,but now I don't want to show sharp edges on images.I want them to blur towards edges..please guide me on how can i use z-index for achieving the same
-
Marckaraujo almost 11 years@Sergey, I can't make this work with your solution, could you post a example? thx
-
Daniel L. over 10 years@Shruti - just add an overlay image with the effect you want
-
José Barbosa over 10 yearsjust adding a note: with this solution when you slide from page 1 to page 2, the page 3 isn't in memory, so it will appear with a delay. to fix this just add - yourViewPager.setOffscreenPageLimit(2);
-
Yugesh about 10 yearsam try this example it works perfectly in emulator but not work in Samsung real device.it overlaps the images.
-
Swayam about 10 yearsI do the same but it disables the over-scroll effect for the last item. Any leads on that ?
-
Swayam about 10 yearsI do the same but it disables the over-scroll effect for the last item. Any leads on that ?
-
CommonsWare about 10 years@Swayam: I actually haven't used Dave's technique much. I tend to go with the
getPageWidth()
solution (see option #1), which still supports overscroll. -
Swayam about 10 yearsThanks for your prompt reply sir! I am yet to try the solution out! But until now, what I have been experiencing is that as soon as give padding to the Pager, the last page doesn't have the overscroll effect. Funnily though, the first one still has overscroll. Would you have any idea?
-
CommonsWare about 10 years@Swayam: As I noted, I haven't used Dave's technique much, and so I have no idea how it behaves with respect to overscroll.
-
Swayam about 10 yearsAlright sir! I will try your solution then! Thanks much! :)
-
Swayam about 10 years@CommonsWare : Sir, I tried your solution! It worked pretty well. The overscroll is there. Only problem now is that the next card shows, but not the previous card. That is, if I am on page 2, I can see page 3 peeking out, but not page 1. Where could I have been going wrong?
-
CommonsWare about 10 years@Swayam: You aren't "going wrong". That is how the first technique works.
-
Swayam about 10 yearsSo, what do I have to do to preserve the overscroll and also show both the previous and next page ?
-
CommonsWare about 10 years@Swayam: I have no idea.
-
Swayam about 10 yearsNo problem sir. I will figure something from your blogpost. Thanks for all the help. :)
-
kenyee about 10 yearsI can't seem to get this to work either...the margins seem to display randomly if I use images w/ scale set to center crop. Anyone have a working code example they can share?
-
CoDe over 9 years@CommonsWare your solution work pretty well..is there way to make left/right side view semi transparent and then gradually start visibility as it start to come in centre. Please suggest.
-
Greg Ennis over 9 yearsBeware that this solution calls setOnPageChangeListener(...). There can only be one page change listener for a viewpager. Therefore you need to add code to relay the listener through the container otherwise you get weird artifiacts due to redraw problems.
-
Greg Ennis over 9 yearsThis should be correct answer. I think maybe this didnt work in prior versions of viewpager but it works now.
-
Umesh Aawte about 9 yearsIts adding same margin on left side of first and right side of last page as well. Any fix
-
akash89 over 8 yearsGood solution provided.
-
Nick over 8 yearsThis doesn't work for first time when using custom page transformers. After a bit of scrolling, it works. Any suggestions please?
-
Imran Ahmed over 8 yearsShort and more Clear answer.
-
Mr T almost 8 yearsIs there a way to make the next item and the preview item blurred, then when on focus remove the blur ?
-
CommonsWare almost 8 years@MrG: You could overlay the
ViewPager
with something that applies the blur on the sides. There are probably better solutions; you may want to ask a separate Stack Overflow question on this. -
Aditya Vyas-Lakhan over 7 years@CommonsWare i tried that demo..but the issue is that i am not able to get my last item position.
-
HannahCarney over 7 yearseasiest and best way
-
hardik9850 almost 7 yearsHow to touch first and last item? By checking page index in OnPageListener?
-
silentsudo almost 6 yearsThis is the beast yes beast answer for consider naming values xd
-
voytez over 5 yearsside note: this wont work with a custom view pager transformer
-
Anooj Krishnan G over 5 yearsWhen I try to zoom the center layout, its zooming to top and bottom. The left and right is not visible due to the padding. Please see the question stackoverflow.com/questions/52710076/…
-
Alex over 5 years@voytez any solution for transformer ?
-
Chirag Joshi over 5 yearsThis code is not working properly, its showing left side page bit bigger than right side
-
Phong Nguyen about 5 years@CommonsWare it works as expected but it remove corner radius of CardView? any help to fix this please?
-
CommonsWare about 5 years@ThinkTwiceCodeOnce: This question does not appear to have anything to do with
CardView
. You should be able to callsetRadius()
on aCardView
to change its radius. If you have further concerns in this area, and you are not finding any existing questions that cover it, ask a fresh question. -
Saeid Z over 3 yearsThanks. How to increase space between pages?
-
44kksharma over 3 yearsmPager.setPageMargin(marging in pixels);
-
oziomajnr almost 3 yearsHow can we make the off screen items respond to click events.
-
CommonsWare almost 3 years@oziomajnr: You would do it the same way as you would anything else in a
ViewPager
: add click listeners to the widgets. However, for items that are fully off-screen, the user has no visible pixels of those widgets to click. -
oziomajnr almost 3 yearsI have tried setting on click listeners to the off screen elements but because they are drawn outside the parent, they do not respond to click events.
-
CommonsWare almost 3 years@oziomajnr: You might try switching to
ViewPager2
, asViewPager
itself largely is deprecated. Beyond that, consider asking a separate Stack Overflow question with a minimal reproducible example demonstrating what you are trying and explaining in detail what you are seeing.