InfiniteViewPager icon indicating copy to clipboard operation
InfiniteViewPager copied to clipboard

Scrolling back works incorrect if adapter has less than 4 pages

Open danikula opened this issue 13 years ago • 8 comments

Scrolling back works incorrect if adapter has less than 4 pages. To reproduce bug just use array

int[] colours = new int[] { Color.CYAN, Color.GRAY, Color.MAGENTA};

in InfiniteViewPagerActivity and try scroll back.

danikula avatar Jul 04 '12 18:07 danikula

When you have three pages, the offscreen page being created as you scroll is the same one being destroyed. This is not a problem when you scroll forward because it will be destroyed and then created (in that order). When you scroll backwards, it will be created and then destroyed, the net effect being a blank page.

I have experimented with trying to block destroyItem() / calling instantiateItem() again if you are creating/destroying a page in the same round (between startUpdate() and finishUpdate()), but I didn't think it worked reliably enough and different implementations of destroyItem()/instantiateItem() produced different results.

If you have a simple solution that works well with both FragmentPagerAdapter and FragmentStatePagerAdapter for low page counts, please let me know. For the time being, having less than four pages is unfortunately unsupported.

antonyt avatar Jul 07 '12 13:07 antonyt

I can reproduce this issue. but if I use InfinitePagerAdapter with PagerAdapter instead of FragmentPagerAdapter, it works well for less than 4 page(2, 3). Because for PagerAdapter, object in instantiateItem and object in destroyItem are different but for FragmentPagerAdapter both are same.

EaseTheWorld avatar Apr 30 '13 04:04 EaseTheWorld

I have same issue with my circular ViewPager, like antonyt said, if scroll backwards, previous page will be created then destoryed immdiately,After few hours' trying, I found a solution below. 1 this is part of code in my ViewPagerCircularAdapter, which extends FragmentPagerAdapter. If ViewPager trying to detach item which left to current item, I just let it be attached again, by calling super.instantiateItem(container, position % tabs.size()); It works for me well!

jaredlam avatar May 24 '13 06:05 jaredlam

For less than 4 pages I changed destroyItem() method in InfinitePagerAdapter(which extends PagerAdapter) as follows and it works like a charm for me..I hope this will help others.

 @Override
 public void destroyItem(ViewGroup container, int position, Object object) {
        int virtualPosition = position % getRealCount();
       debug("destroyItem: real position: " + position);
       debug("destroyItem: virtual position: " + virtualPosition);

     // only expose virtual position to the inner adapter
     adapter.destroyItem(container, virtualPosition, object);

     if (getRealCount() < 4) {
         adapter.instantiateItem(container, virtualPosition);
    return;
 }

}

ketanahir avatar Aug 13 '13 12:08 ketanahir

Hi, I applied the fix suggested by ketanahir, but it is not working if you have only 1 or 2 elements to display. Do you have another tip? Many Thanks in advance! Daniele

danieledb avatar Sep 21 '13 16:09 danieledb

Anyway, FYI, I applied a workaround: multiply data to display in order to make sure that they are at least 4. It works perfectly :)

danieledb avatar Sep 21 '13 17:09 danieledb

None of the above fixes worked for me; however, I have found that a simple fix is to ensure that 3 pages are always kept in memory, so the first 2 pages are never destroyed on scrolling backwards. This has implications for memory usage, but it should be negligible on most (all?) devices.

gallery = (InfiniteViewPager) this.getView().findViewById(R.id.galleryFullscreenListingPhotos);
// ...
gallery.setAdapter(adapter);
gallery.setOffscreenPageLimit(2);

hndmrsh avatar Apr 16 '14 23:04 hndmrsh

The simple way to fix it is to copy the data in order to make that they are more than 4 pages with duplicated data ,just as danieledb did.

jumanjihu avatar Jun 21 '16 08:06 jumanjihu