2012-04-17 50 views
9

Tôi có một ViewPager với một số giao diện. Tôi muốn đi đến cái đầu tiên sau khi vuốt sang phải cái cuối cùng.Cách tạo vòng lặp ViewPager?

tôi đã cố gắng

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

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

Nhưng tôi đã nhận ra lỗi

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

việc kiểm tra này http://stackoverflow.com/q/7546224/1263908 – sique

+0

http://stackoverflow.com/questions/7440012/infinite-viewpager – blessenm

Trả lời

5

tôi sẽ tạo ra một trang giả ở phần cuối của ViewPager. Sau đó, tôi sử dụng mã này để chuyển đến trang đầu tiên khi người dùng cuộn đến trang giả. Tôi biết đó là xa hoàn hảo: D

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

nếu bạn làm điều này cách, có bạn có thể đạt được cuộn vô hạn nhưng khi cuộn trong trang cuối cùng, bạn sẽ thấy các hình ảnh động như quay trở lại scren1 .. –

24

Một khả năng được thiết lập màn hình như thế này:

C 'ABCA'

C' trông giống như C, nhưng khi bạn di chuyển đến đó , nó sẽ chuyển bạn đến thực C. A' trông giống như A, nhưng khi bạn di chuyển đến đó, nó chuyển bạn đến A. thực

tôi sẽ làm điều này bằng cách thực hiện onPageScrollStateChanged như vậy:

@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); 
     } 
    } 
} 

Lưu ý rằng điều này gọi dạng thay thế setCurrentItem và chuyển số false để làm cho bước nhảy xảy ra ngay lập tức thay vì cuộn trơn tru.

Có hai nhược điểm chính mà tôi thấy. Thứ nhất, khi đạt đến một trong hai đầu người sử dụng phải để cho di chuyển giải quyết trước khi họ có thể đi xa hơn. Thứ hai, nó có nghĩa là có một bản sao thứ hai của tất cả các khung nhìn trong trang đầu tiên và trang cuối cùng của bạn. Tùy thuộc vào cách tài nguyên của bạn nặng màn hình, có thể loại trừ kỹ thuật này như là một giải pháp có thể. Cũng cần lưu ý rằng vì trình xem trang không cho phép các nhấp chuột đi qua các điều khiển cơ bản cho đến sau khi cuộn xong, có thể không thiết lập danh sách nhấp chuột và các loại tương tự cho đoạn A 'và C'.

Chỉnh sửa: Giờ đây đã tự thực hiện điều này, có một nhược điểm khá lớn khác. Khi nó chuyển từ A 'sang A hoặc C' sang C, màn hình sẽ nhấp nháy một lúc, ít nhất là trên thiết bị kiểm tra hiện tại của tôi.

+0

Câu trả lời tuyệt vời! Tôi đã sử dụng nó và nó hoạt động hoàn hảo! – vandzi

+0

Xin chào, bạn có thể tìm thấy cách để tránh nhấp nháy không? – RMalke

+0

Giải pháp tuyệt vời cho nhiệm vụ của tôi! Thx – mbelsky

0

này nên thực hiện công việc mà không cần trang giả:

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

làm việc này, câu trả lời được chấp nhận không tốt bởi vì có một sự chậm chạp khi vòng lặp xảy ra:

@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); 
} 

câu trả lời lấy từ đây: ViewPager as a circular queue/wrapping

1

Giải pháp của tôi dựa trên benkc, nhưng hoạt ảnh cuộn trang đầu tiên và cuối cùng bị vô hiệu hóa và khi các trang "cuộn" đến trang thực, hoạt ảnh cuộn được bật lại, Đề án này có thể giải quyết nhược điểm đầu tiên.

nhưng kết quả ViewPager.setCurrentItem(position, false) của tôi vẫn có hoạt ảnh cuộn, vì vậy tôi triển khai hoạt ảnh quá nhanh để xem.

sự di chuyển hình ảnh động nhanh như thế này, không quan tâm nhận xét, chỉ cần mã của tôi không sử dụng các phương pháp:

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); 
    } 
} 

và sử dụng phương pháp này để hoạt động ViewPager của

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(); 
    } 
} 

và sửa đổi onPageScrollStateChanged như thế này, chỉ trang đầu tiên hoặc trang cuối cùng (tôi có 5 trang) sẽ thay đổi hoạt ảnh để cuộn nhanh, nếu không có cuộn bình thường:

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); 
     } 
    } 
} 

tài liệu tham khảo FixedSpeedScroller là ở đây: http://blog.csdn.net/ekeuy/article/details/12841409

Các vấn đề liên quan