2012-04-17 63 views
9

我有一個ViewPager的一些意見。我想在最後一次右擊之後去第一個。如何製作ViewPager循環?

我試圖

@Override 
public Fragment getItem(int arg0) { 
    int i = arg0 % fragmentList.size(); 
    return fragmentList.get(i); 
} 

@Override 
public int getCount() { 
    return fragmentList.size()+1; 
} 

但我得到了一個錯誤

E/AndroidRuntime(22912): java.lang.IllegalStateException: Fragment already added: RubricFragment{4136cd80 #1 id=0x7f06000c android:switcher:2131099660:0} 
+0

檢查這個 http://stackoverflow.com/q/7546224/1263908 – sique 2012-04-17 08:53:47

+0

http://stackoverflow.com/questions/7440012/infinite-viewpager – blessenm 2012-04-17 08:59:15

回答

5

我將在ViewPager年底創建一個虛擬頁面。 然後,當用戶滾動到虛擬頁面時,我使用此代碼轉到第一頁。我知道這是遠遠不夠完善:d

@Override 
public void onPageScrolled(int position, float arg1, int arg2) { 
    if (position >= NUM_PAGE-1) { 
     mViewPager.setCurrentItem(0, true); 
    } 
} 
+0

如果你這樣做方式,是的,你可以實現無限滾動,但在最後一頁滾動時,你會看到動畫像回到scren1 .. – 2017-01-17 06:46:32

24

一種可能性是建立這樣的畫面:

C「ABCA」

C」看起來就像C,但是當你滾動到那裏,它可以切換到真正的C. A」看起來就像一個,但是當你滾動到那裏,它可以切換到真正A.

我將通過實施onPageScrollStateChanged像這樣做:

@Override 
public void onPageScrollStateChanged (int state) { 
    if (state == ViewPager.SCROLL_STATE_IDLE) { 
     int curr = viewPager.getCurrentItem(); 
     int lastReal = viewPager.getAdapter().getCount() - 2; 
     if (curr == 0) { 
      viewPager.setCurrentItem(lastReal, false); 
     } else if (curr > lastReal) { 
      viewPager.setCurrentItem(1, false); 
     } 
    } 
} 

請注意,這會調用setCurrentItem的替代形式並傳遞false以使跳轉立即發生,而不是平滑滾動。

我看到這個有兩個主要缺陷。首先,在達到任何一端時,用戶必須先讓滾動結束,然後再繼續前進。其次,這意味着在第一頁和最後一頁中都有第二個副本。取決於屏幕的資源量,這可能會排除這種技術作爲一種可能的解決方案。

還要注意,由於視圖尋呼機不讓點擊通過底層控件,直到滾動結算之後,可能沒有爲A'和C'片段設置clicklisteners等。

編輯:現在自己實現了這個,還有另一個主要的缺點。當它從A'切換到A或C'切換到C時,屏幕至少會在當前的測試設備上閃爍片刻。

+0

很好的答案!我用它,它工作完美! – vandzi 2012-11-05 15:41:39

+0

嗨,你能找到一種避免閃爍的方法嗎? – RMalke 2012-11-15 00:19:32

+0

我的任務的驚人的解決方案! Thx – mbelsky 2014-06-30 10:27:25

0

本應該做的工作,而不啞頁:

private boolean isFirstOrLastPage; 
private int currentPageIndex = 0; 


@Override 
public void onPageScrolled(int arg0, float arg1, int arg2) { 
    if(currentPageIndex!=arg0){ 
     isFirstOrLastPage = false; 
     return; 
    } 
    if((arg0==0 || arg0==PAGES.size()-1) && arg1 == 0 && arg2 == 0){ 
     if(isFirstOrLastPage){ 
       //DO SOMETHING 
     }else{ 
      isFirstOrLastPage = true; 
     } 
    } 
} 

@Override 
public void onPageSelected(int arg0) { 
    currentPageIndex = arg0; 
} 
0

這個作品中,公認的答案沒有好,因爲有一個滯後,當循環發生了:從這裏取

@Override 
public int getCount() { 
    return Integer.MAX_VALUE; 
} 

@Override 
public CharSequence getPageTitle(int position) { 
    String title = mTitleList.get(position % mActualTitleListSize); 
    return title; 
} 

@Override 
public Object instantiateItem(ViewGroup container, int position) { 
    int virtualPosition = position % mActualTitleListSize; 
    return super.instantiateItem(container, virtualPosition); 
} 

@Override 
public void destroyItem(ViewGroup container, int position, Object object) { 
    int virtualPosition = position % mActualTitleListSize; 
    super.destroyItem(container, virtualPosition, object); 
} 

答案: ViewPager as a circular queue/wrapping

1

我的解決方案基於benkc,但第一頁和最後一頁滾動動畫被禁用,當頁面「滾動」到實際頁面時,滾動動畫再次啓用,這個方案可以解決第一個缺點。

但我的ViewPager.setCurrentItem(position, false)結果仍然有滾動動畫,所以我實現的動畫太快而看不到。

快速滾動動畫這個樣子,不介意的評論,只是我的代碼沒有使用這些方法:

public class FixedSpeedScroller extends Scroller { 
    private int mDuration = 0; 

    public FixedSpeedScroller(Context context) { 
     super(context); 
    } 

    @Override 
    public void startScroll(int startX, int startY, int dx, int dy, int duration) { 
     super.startScroll(startX, startY, dx, dy, mDuration); 
    } 

    @Override 
    public void startScroll(int startX, int startY, int dx, int dy) { 
     super.startScroll(startX, startY, dx, dy, mDuration); 
    } 
} 

,並用這種方法來viewpager的活動

private Scroller scroller; 
private void setViewPagerScroll(boolean instant) { 
    try { 
     Field mScroller = null; 
     mScroller = ViewPager.class.getDeclaredField("mScroller"); 
     mScroller.setAccessible(true); 
     if (scroller == null) { 
      scroller = (Scroller) mScroller.get(mViewPager); 
     } 
     FixedSpeedScroller fss = new FixedSpeedScroller(mViewPager.getContext()); 
     mScroller.set(mViewPager, instant ? fss : scroller); 

    } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { 
     e.printStackTrace(); 
    } 
} 

和像這樣修改onPageScrollStateChanged,只有第一頁或最後一頁(我有5頁)會改變動畫快速滾動,否則有正常滾動:

public void onPageScrollStateChanged(int state) { 
    if (state == ViewPager.SCROLL_STATE_IDLE) { 
     if (position == 0) { 
      setViewPagerScroll(true); 
      mViewPager.setCurrentItem(3); 

     } else if (position == 4) { 
      setViewPagerScroll(true); 
      mViewPager.setCurrentItem(1); 

     } else { 
      setViewPagerScroll(false); 
     } 
    } 
} 

FixedSpeedScroller引用是在這裏:http://blog.csdn.net/ekeuy/article/details/12841409