10

いくつかのビューを持つ 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}
4

6 に答える 6

29

1 つの可能性は、次のように画面を設定することです。

C'ABCA'

C' は C と同じように見えますが、そこまでスクロールすると実際の C に切り替わります。A' は 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、スムーズなスクロールではなく瞬時にジャンプすることに注意してください。

これには 2 つの主な欠点があります。まず、どちらかの端に到達すると、ユーザーは先に進む前にスクロールを落ち着かせる必要があります。次に、最初と最後のページのすべてのビューの 2 番目のコピーを持つことを意味します。画面のリソースがどの程度重いかによっては、この手法が可能な解決策として除外される場合があります。

また、ビュー ページャーは、スクロールが安定するまで下層のコントロールにクリックを通過させないため、A' および C' フラグメントに対してクリック リスナなどを設定しなくても問題ないことにも注意してください。

編集:これを自分で実装したので、別のかなり大きな欠点があります。A' から A または C' から C に切り替わると、少なくとも現在のテスト デバイスでは、画面がちらつきます。

于 2012-10-19T00:36:15.853 に答える
6

ViewPager の最後にダミー ページを作成します。次に、このコードを使用して、ユーザーがダミー ページにスクロールしたときに最初のページに移動します。私はそれが完璧にはほど遠いことを知っています:D

@Override
public void onPageScrolled(int position, float arg1, int arg2) {
    if (position >= NUM_PAGE-1) {
        mViewPager.setCurrentItem(0, true);
    }
}
于 2012-09-03T05:10:39.787 に答える
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;
}
于 2014-05-28T11:45:20.970 に答える
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

于 2015-05-29T15:12:48.247 に答える