Tuesday, August 26, 2014

Looping ViewPager - Small hack to make ViewPager loop through screens

For my Android app, I am using ViewPager to get a cool animation navigating by swiping cards left and right. The supporting Android class FragmentStatePagerAdapter does all the heavy lifting but also restricts few features.

For example, I was looking for a looping ViewPager, where on first swiping back from first page takes you to last page, as well on swiping forward on last page takes you back again to the first page and this loop continues.

I checked on stackoverflow for any clean solutions, but I was not satisfied with the hacks detailed over there. I did some brainstorming and started working on my own design.

So, I decided instead of having "n" pages in my ViewPager, I will have "n+2", that is additional 2 pages. I have 2 variables here, position - a zero index based variable specifying page number in ViewPager and contentIndex - an index of string array I am displaying as ViewPager cards. These additional 2 pages would be the first page at position 0 which would display the content at the last index of array, and the last page at position n+1 which would display the content at index 0. Thus for content at index 0 and n are being displayed by 2 pages.

Then I listen for OnPageChange events. For these 2 special pages, as soon as I land on them, instead of displaying these pages, I switch the page to go to the original page that was already displaying it at its proper position. I navigate to it without any animation.

For e.g. if I come to position 0 which displays the last content of array, instead of being at position 0, I switch it to position n which was displaying the same content. The switch is instantaneous, although if you watch closely, you will notice a sort of jerk that happens. Similarly I switch to page at position 1 as soon as I land on page at position n+1.

A project with complete implementation of above hack can be found on Github @anagri/ViewPagerLoop

The screenshots from the above app looks like -



The core logic in code is ->


If you found this helpful or have any suggestions, kindly leave a comment.
Thanks

6 comments:

  1. If you used modulo arithmetic, you could simplify even further because you wouldn't have to reset the counter. (you'd have to handle swiping left past 0 though... I haven't worked that one out in my head fully yet)

    ReplyDelete
    Replies
    1. This approach was given on stackoverflow as well but I resisted using this. The main reason being FragmentStatePagerAdapter has 2 array lists where it stores either the state or the complete fragment as cache. If you keep swiping in the same direction, you would keep increasing the size of these lists. Because of this reason, I came with this approach which only adds 2 additional pages and restricts those lists from blowing off.

      Delete
  2. Hi
    can use it to show the value of an array of ten elements not?

    ReplyDelete
  3. Thanks! This works like a charm. One improvement is rather than calling setCurrentItem() in onPageSelected(), instead save the index and defer the call to setCurrentItem() to onPageScrollStateChanged(). There you can test if the state is idle and loop to the saved index. That way you dont get any pause in the animation.

    ReplyDelete
  4. I have read your blog its very attractive and impressive. I like it your blog.

    Java Training in Chennai Core Java Training in Chennai Core Java Training in Chennai

    Java Online Training Java Online Training JavaEE Training in Chennai Java EE Training in Chennai

    ReplyDelete
  5. Thank you for taking the time to provide us with your valuable information. We strive to provide our candidates with excellent care and we take your comments to heart.As always, we appreciate your confidence and trust in us
    Java Training in Chennai

    ReplyDelete