79

I'm using the following example to impliment my viewPager: http://code.google.com/p/viewpagerexample/issues/list

The problem with this example is that I can't figure out how to set my starting position, the default starting position is 0. Basically I wan't to be able to control if there is an available view on its left or the right.

Is there any way to control center's View current position? is there a better way to do it? is it possible to make it circular?

mohax
  • 4,435
  • 2
  • 38
  • 85
Kirill Kulakov
  • 10,035
  • 9
  • 50
  • 67

9 Answers9

176

I've found a way to set it's position, which is done outside of the class:

 awesomePager = (ViewPager) findViewById(R.id.awesomepager);
 awesomePager.setAdapter(awesomeAdapter);
 awesomePager.setCurrentItem(CurrentPosition);

and it can be limited by calculating the amount of items I want to fit in to it

Kirill Kulakov
  • 10,035
  • 9
  • 50
  • 67
  • 4
    note that if `awesomeAdapter` is backed by a Cursor/LoaderManager you'll need to be careful about when `setCurrentItem` is called to avoid stealing focus (too late) or failing to move the page at all (too early) - see [this](http://stackoverflow.com/a/24174114/404960) – rymo Jun 12 '14 at 14:46
  • did not work for me because my other fragments are not ready at that point and I've got an exception since my app tried to use a variable from the `currentPosition` fragment that was not created yet – Zvi Apr 18 '16 at 19:04
  • Working Perfect. Setting view pager when fragment is ready works fine, tried this when fragment is ready and you have currentposition available. Thanks @Kirill – Naeem Ibrahim Oct 25 '16 at 13:04
  • Is there any way to start ViewPager from the **end**? I mean like in _RecyclerView_, when you set up `new LinearLayoutManager(..., inverse=true)` . What I want is: ViewPager jump immidiately to the last item, without fire up fragments in the middle – murt Feb 10 '17 at 11:54
  • 1
    @murt it's pretty late, but in case someone has the same issue, passing `false` wouldn't show the user the transition that happens: `viewPager.setCurrentItem(newPosition, false);` – Yousef Gamal Oct 05 '19 at 01:17
  • I think the issue here is that the pager will start a position zero, then page to "CurrentPosition" thus instantiating fragments which don't need instantiation. – the_prole Mar 15 '20 at 00:26
20

I have noticed that if you recreate Activity (orientation change) with ViewPager having FragmentStatePagerAdapter, then the Adapter will reuse it's Fragments. The way to stop it is:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    if (viewPager != null) {
        // before screen rotation it's better to detach pagerAdapter from the ViewPager, so
        // pagerAdapter can remove all old fragments, so they're not reused after rotation.
        viewPager.setAdapter(null);
    }
    super.onSaveInstanceState(savedInstanceState);
}

but then after Activity recreation ViewPager alwayes opens page 0 first and setCurrentItem(CurrentPosition); doesn't work. Fix for that is changing page after delay:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        viewPager.setCurrentItem(newPosition);
    }
}, 100);
Malachiasz
  • 7,126
  • 2
  • 35
  • 49
18

To start with the last fragment I did this:

PagerAdapter pagerAdapter = new PagerAdapter();
viewPager.setAdapter(pagerAdapter);
viewPager.setCurrentItem(pagerAdapter.getCount() - 1);
Sujay U N
  • 4,974
  • 11
  • 52
  • 88
Helali
  • 196
  • 1
  • 6
11

I came across a problem whereby if I set the current item before I set the adapter, the first item I get back will always be the one at position 0.

Make sure you do:

awesomePager.setAdapter(awesomeAdapter);
awesomePager.setCurrentItem(CurrentPosition);

and not:

awesomePager.setCurrentItem(CurrentPosition);
awesomePager.setAdapter(awesomeAdapter);
DaveB
  • 111
  • 1
  • 3
6

I have an array of size more than 1000 and in dymanic viewpager I was facing leftswipe stuck on firstload. The below code solved this and resulted in smooth scroll:

@Override
onResume(){
   super.onResume();
   viewPager.setCurrentItem(newPosition);
}
Suhail k khan
  • 103
  • 2
  • 12
5

I'm using 3 fragments and on starting my app, the second (middle) fragment will be shown by default. Just I'm using the onResume function and all works great.

@Override
protected void onResume() {
    super.onResume();
    m_viewPager.setCurrentItem(1);
}
Leebeedev
  • 2,126
  • 22
  • 31
  • Worked for me as opposed to using a timer in onCreate. Thanks! – Gmeister4 Mar 06 '16 at 12:28
  • did not work for me because my 2nd fragment is not ready at that point and I've got an exception since my app tried to use a variable from the 2nd fragment that was not created yet – Zvi Apr 18 '16 at 19:02
  • So how you could use a variable that not even created ?! – Leebeedev Apr 19 '16 at 08:31
5

Using viewPager.setCurrentItem(newPosition); shows to the user the transition from the starting page to the newPosition, to prevent that from happening and show the newPosition directly as if it was the starting point, I added false to the second parameter something like this:

int newPosition = pages.size()-1; // Get last page position

viewPager.setCurrentItem(newPosition, false); // 2nd parameter (false) stands for "smoothScroll"
Yousef Gamal
  • 1,026
  • 2
  • 17
  • 32
2

I encountered same problem. When I initialize ViewPager, the indicator position was 0. This may depends on amount of calculating for Pager contents. I use ViewTreeObserver like below.

mGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        mViewPager.setCurrentItem(newPosition);
        removeOnGlobalLayoutListener(mSlidingTabLayout.getViewTreeObserver(), mGlobalLayoutListener);
    }
};
mSlidingLayout.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalLayoutListener);

and,

private void removeOnGlobalLayoutListener(ViewTreeObserver observer, ViewTreeObserver.OnGlobalLayoutListener listener) {
       if (observer == null) return;
       if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
               observer.removeGlobalOnLayoutListener(listener);
       } else {
               observer.removeOnGlobalLayoutListener(listener);
       }
} 

In this way, also never to bother with time setting of delay.

chanzmao
  • 101
  • 1
  • 6
1
@Override
public Object instantiateItem(ViewGroup container, int position) {
    View currentPage = null;
    switch(position){
        case 0:
            currentPage = LayoutInflater.from(context).inflate(R.layout.page0, null)    
            break;
        case 1:
            currentPage = LayoutInflater.from(context).inflate(R.layout.page1, null)    
            ///////////// This page will be default ////////////////////
            ((ViewPager)container).setCurrentItem(position);
            ////////////////////////////////////////////////////////////
            break;
        case 2:
            currentPage = LayoutInflater.from(context).inflate(R.layout.page2, null)    
            break;
    return currentPage;
}
Yan
  • 1,569
  • 18
  • 22