7

All I want to do is a horizontal carousel in Android.

If I have 3 screens A B and C then I want my ViewPager to allow me to move like A <-> B, B <-> C, C <-> A.

GTalk for Android's conversation can be switched like this. Samsung's homescreen and application screen can be switched like this.

A B and C are fragments and I'm using an adapter that extends FragmentPagerAdapter. All the fragments will contain a webview.

I have looked here here and here but none of them seem to be doing what I want.

Can anyone guide me in the right direction?

Community
  • 1
  • 1
Sudarshan Bhat
  • 3,722
  • 2
  • 24
  • 51
  • You can check [this tutorial](http://thedeveloperworldisyours.com/android/carousel-viewpager/#sthash.rtkOS5m2.J9bGU21I.dpbs) and this [example in GitHub](https://github.com/thedeveloperworldisyours/CarouselViewPager) – Cabezas Apr 21 '17 at 08:02

3 Answers3

4

(Cross-posting my answer from an identical StackOverflow question)

One possibility is setting up the screens like this:

C' A B C A'

C' looks just like C, but when you scroll to there, it switches you to the real C. A' looks just like A, but when you scroll to there, it switches you to the real A.

I would do this by implementing onPageScrollStateChanged like so:

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

Note that this calls the alternate form of setCurrentItem and passes false to cause the jump to happen instantly rather than as a smooth scroll.

There are two main drawbacks I see to this. Firstly, upon reaching either end the user has to let the scrolling settle before they can go further. Secondly, it means having a second copy of all of the views in your first and last page. Depending on how resource-heavy your screens are, that may rule out this technique as a possible solution.

Note also that since the view pager doesn't let clicks go through to underlying controls until after the scrolling has settled, it's probably fine to not set up clicklisteners and the like for the A' and C' fragments.

Edit: Having now implemented this myself, there's another pretty major drawback. When it switches from A' to A or C' to C, the screen flickers for a moment, at least on my current test device.

Community
  • 1
  • 1
benkc
  • 3,044
  • 1
  • 25
  • 37
  • I have tried this already. There are other additional problems. If some view has changed in A then A` should also reflect the same. Like if you've scrolled in A and then if you go to A` it will show you the unscrolled screen for a second and causes flicker again. – Sudarshan Bhat Oct 19 '12 at 07:04
1

ViewPager settings:

    mViewPager = (ViewPager) findViewById(R.id.view_pager);
    mViewPager.setAdapter(new YourPagerAdapter(getSupportFragmentManager()));
    //Set the number of pages that should be retained to either side of the current page.
    mViewPager.setOffscreenPageLimit(1);
    mViewPager.setCurrentItem(50);

FragmentPagerAdapter:

public class YourPagerAdapter extends FragmentPagerAdapter {
    final int PAGE_COUNT = 100;
    final int REAL_PAGE_COUNT = 3;

    public YourPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        while (position > REAL_PAGE_COUNT - 1) {
            position = position - REAL_PAGE_COUNT ;
        }

        switch (position) {
            case 0:
                return FirstFragment.newInstance(position);
            case 1:
                return SecondFragment.newInstance(position);
            case 2:
                return ThirdFragment.newInstance(position);
        }
        return null;
    }

    @Override
    public int getCount() {
        return PAGE_COUNT;
    }
}
Alexey
  • 4,014
  • 1
  • 23
  • 29
0

Implement the getItem(int position) like this:

public Fragment getItem(int position)
{
    switch(position)
    {
        case 0:
        Fragment A = new A();
        return A;
        case 1:
        Fragment B = new B();
        return B;
        same for C....
    }
}

you can also have a look at here: SimpleViewPager.. download the source and understand it. Hope it helps.

Farhan
  • 12,674
  • 2
  • 29
  • 58