Вопрос по android-fragments, android, loops – Как сделать цикл ViewPager?

9

У меня есть ViewPager с некоторыми представлениями. Я хотел бы перейти к первому после того, как справа пролистал последний.

Я старался

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

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

Но я получил ошибку

<code>E/AndroidRuntime(22912): java.lang.IllegalStateException: Fragment already added: RubricFragment{4136cd80 #1 id=0x7f06000c android:switcher:2131099660:0}
</code>
Проверь этоstackoverflow.com/q/7546224/1263908 sique

Ваш Ответ

5   ответов
6

Я бы создал фиктивную страницу в конце ViewPager. Затем я использую этот код для перехода на первую страницу, когда пользователь прокручивает страницу-заглушку. Я знаю, что это далеко от совершенства: D

@Override
public void onPageScrolled(int position, float arg1, int arg2) {
    if (position >= NUM_PAGE-1) {
        mViewPager.setCurrentItem(0, true);
    }
}
Error: User Rate Limit Exceeded
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 как круговая очередь / перенос

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

Одна из возможностей - настроить экраны следующим образом:

С & APOS; A B C A ';

С & APOS; выглядит так же, как C, но когда вы прокручиваете туда, он переключает вас на настоящий C. & APOS; выглядит так же, как А, но когда вы прокручиваете туда, он переключает вас на настоящий А.

Я бы сделал это путем реализации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 '; и С '; фрагменты.

Edit: Теперь, когда я сам это реализовал, есть еще один довольно существенный недостаток. Когда он переключается с A & a; А или С '; до C, экран мигает на мгновение, по крайней мере, на моем текущем тестовом устройстве.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
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);
    }
}

и использовать этот метод для просмотра действий пейджера

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

Похожие вопросы