ViewPager как круговая очередь / перенос - PullRequest
63 голосов
/ 25 сентября 2011

Я использую ViewPager с FragmentStatePagerAdapter, чтобы разрешить навигацию между некоторыми фрагментами.

Допустим, у меня есть три фрагмента: A, B и C.ViewPager сначала показывает фрагмент A и позволяет вам перейти к фрагменту B, проводя справа налево, а затем к фрагменту C, проводя снова.Это позволяет использовать следующие навигационные пути: A <--> B <--> C.

. Мне хотелось бы иметь возможность проводить пальцем слева направо на фрагменте A и иметь ViewPager, отображающий фрагмент C, т.е. чтобы он вел себя каккруговая очередь и разрешить ... --> C <--> A <--> B <--> C <--> A <-- ...

Я не хочу, чтобы фрагменты дублировались в других позициях (т. е. заканчиваются более чем тремя экземплярами).

Возможна ли эта функция обертывания с помощью ViewPager?

Ответы [ 13 ]

0 голосов
/ 15 декабря 2015
  1. Набор для элементов подсчитать некоторое большое значение, скажем, 500000.
  2. Возвратите из адаптера это значение * количество актуальных предметов.
  3. На getItem (int i) настройте i на -> i = i% количества фактических элементов.
  4. On onCreate (Bundle saveInstanceState) установить текущий элемент для страницы 500000/2

    public class MainActivity extends FragmentActivity {
    
        private final static int ITEMS_MAX_VALUE = 500000;
        private int actualNumCount = 10;
        private ViewPager mPager = null;
    
        private class OptionPageAdapter extends FragmentStatePagerAdapter {
            public OptionPageAdapter(FragmentManager fm) {
                super(fm);
            }
    
            @Override
            public Fragment getItem(int i) {
                try {
                    i = i % OptionType.values().length;
                    OptionPage optionPage = new OptionPage(i);
                    optionPage.id = i;
                    return optionPage;
                } catch (Exception e) {
                    VayoLog.log(Level.WARNING, "Unable to create OptionFragment for id: " + i, e);
                }
                return null;
            }
    
            @Override
            public int getCount() {
                return ITEMS_MAX_VALUE * actualNumCount;
            }
        }
    
        public static class OptionPage extends Fragment {
            private int id = 0
            @Nullable
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                View mainView = inflater.inflate(R.layout.main_page, container, false);
                return mainView;
            }
    
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            mPager = (ViewPager) findViewById(R.id.main_pager);
            mPager.setOffscreenPageLimit(3);
            mPager.setAdapter(new OptionPageAdapter(this.getSupportFragmentManager()));
            mPager.setCurrentItem(ITEMS_MAX_VALUE/2,false);
    
        }
    
    }
    
0 голосов
/ 06 апреля 2014

Извините за задержку, но я видел ответы, и я не смог удержаться, должен ответить тоже:).

На вашем адаптере в методе get count выполните следующие действия:

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

Это сработает!

0 голосов
/ 03 августа 2013

У меня есть решение, которое, я считаю, сработает.Он не тестировался, но вот он:

Обертка вокруг FragmentPagerAdapter в качестве суперкласса:

public abstract class AFlexibleFragmentPagerAdapter extends
        FragmentPagerAdapter
{
    public AFlexibleFragmentPagerAdapter(FragmentManager fm)
    {
        super(fm);
        // TODO Auto-generated constructor stub
    }

    public abstract int getRealCount();

    public abstract int getStartPosition();

    public abstract int transformPosition(int position);
};

Затем стандартная реализация FragmentPagerAdapter подкласса этого нового абстрактного класса:

public class SomeFragmentPagerAdapter extends
        AFlexibleFragmentPagerAdapter
{

    private Collection<Fragment> someContainer;

    public SomeFragmentPagerAdapter(FragmentManager fm, Container<Fragment> fs)
    {
        super(fm);
        someContainer = fs;
    }

    @Override
    public int getRealCount() { return someContainer.size(); }

    @Override
    public int getStartPosition() { return 0; }

    @Override
    public int transformPosition(int position) { return position; }
};

И реализация адаптера циклического пейджера.

public class SomeCyclicFragmentPagerAdapter extends
        SomeFragmentPagerAdapter 
{
    private int realCount = 0;
    private int dummyCount = 0;
    private static final int MULTI = 3;

    public SomeFragmentPagerAdapter(FragmentManager fm, ...)
    {
        super(fm);
        realCount = super.getCount();
        dummyCount *= MULTI;
    }

    @Override
    public int getCount() { return dummyCount; }

    @Override
    public int getRealCount() { return realCount; }

    @Override
    public int getStartPosition() { return realCount; }

    @Override
    public int transformPosition(int position)
    {
        if (position < realCount) position += realCount;
        else if (position >= (2 * realCount)) position -= realCount;

        return position;
    }
};

Инициализация ViewPager

    this.mViewPager.setCurrentItem(this.mPagerAdapter.getStartPosition());

И, наконец, реализация обратного вызова:

    @Override
    public void onPageSelected(int position)
    {
        this.mTabHost.setCurrentTab(position % mPagerAdapter.getRealCount());
        this.mViewPager.setCurrentItem(this.mPagerAdapter
                .transformPosition(position));
    }

    @Override
    public void onTabChanged(String tabId)
    {
        int pos = this.mTabHost.getCurrentTab();

        this.mViewPager.setCurrentItem(this.mPagerAdapter
                .transformPosition(pos));
    }
...