2

I would like to keep a list of 3 views at all times. The app starts at position 1 (out of positions 0,1,2). When someone scrolls to position 0, I would like to remove view 2, and create a view before position 0. This way, it appears to the user, that there are unlimited views. In the same way, when someone scrolls to position 2, I would like to remove the view at position 0 and add one at the end.

However I'm having problems with both adding and removing views. When I get to position 0, nothing changes unless I try scrolling past position 0 (to position -1, i.e. the boundary is hit). At that point, I can see that it is the boundary of my views, but then setCurrentItem(1,false) is triggered and I'm brought back to the middle of the views. When I scroll to position 2 I see that position 2 has been updated. However position 0 and 1 remain the same.

When I scroll to position 2, nothing happens. However if I try and scroll to the boundary, for some reason, position 0 gets updated and setCurrentItem(1,false) is triggered.

I have no idea why its happening like this. Can anyone shed some light on this?

Here is my code:

public class MainActivity extends Activity {


ArrayList<Integer> showThree = new ArrayList<Integer>();
    int focusedPage = 0;

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        showThree.add(0,5); //adding integers 5,6,7 for positions 0,1,2
        showThree.add(1,6);
        showThree.add(2,7);

        final MyPagerAdapter adapter = new MyPagerAdapter(getApplicationContext(),showThree);
        final ViewPager myPager = (ViewPager) findViewById(R.id.mypanelpager);
        myPager.setAdapter(adapter);
        myPager.setCurrentItem(1);

myPager.setOnPageChangeListener(new OnPageChangeListener(){

        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == ViewPager.SCROLL_STATE_IDLE) {

//when position= 0, change the 3 views from 5,6,7 to 4,5,6. 
                 if (focusedPage == 0) {
                     showThreeMonths.set(0,4);
                     showThreeMonths.set(1,5);
                     showThreeMonths.set(2,6);
                     adapter.notifyDataSetChanged();
                     adapter.startUpdate(myPager);

                     }
                 else if (focusedPage ==2){
                        //ignore, just testing focusPage=0 for now }

                 }

//set current page to the middle of the 3 new views, which would be 
//the same view at position 0 of the old 3 views. 
//Thus user doesn't experience the views changing despite being 3 new views.

             myPager.setCurrentItem(1,false); 

        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPageSelected(int position) {
            focusedPage = position; 

        }

    });
}

PagerAdapter

public class MyPagerAdapter extends PagerAdapter {

private ArrayList<Integer> showThreeMonths;
private Context ctx;

public MyPagerAdapter (Context ctx, ArrayList<Integer> showThree){
    this.ctx = ctx ;
    this.showThree = showThree;
}


@Override
public int getCount() {
    return showThree.size();
}



public Object instantiateItem(ViewGroup collection, int position ){
    //NewCustomView is a class I made that takes parameters context and an integer and creates a view based on the integer
    NewCustomView MyOwnView = new NewCustomView(ctx, showThree.get(position)); 


    View customViewLayout = MyOwnView.newLayout; //part of the class object
    collection.addView(customViewLayout);
    return customViewLayout;
 }


@Override
 public void destroyItem(ViewGroup collection, int position, Object arg2) {
     ((ViewPager) collection).removeView((ViewGroup) arg2);}


 @Override
 public Parcelable saveState() {
     return null;}


@Override
public boolean isViewFromObject(View view, Object arg1) {
    return view==arg1;}
@Override
public void startUpdate(ViewGroup collection) {}

@Override
public void finishUpdate(ViewGroup collection) {}


}
Terence Chow
  • 10,755
  • 24
  • 78
  • 141

1 Answers1

1

The instantiateItem() method creates the 2 view pages in the memory by default. Therefore when you swipe to the second page then 0 page is recreated as it's outside the range of the 2 pages saved in the memory. Please try to use

myViewPager.setOffscreenPageLimit(numberOfPages) 

method that receives an integer as a parameter and declares how many pages it should be keeping before recycling them.

Marcin S.
  • 11,161
  • 6
  • 50
  • 63
  • thanks...so are you saying that I should set the numberOfPages to 0? that way nothing is kept? Also, can you explain why I have to "hit the boundary" of my views before my list is updated? – Terence Chow Sep 20 '12 at 03:45
  • Actually the minimum number of pages kept in the memory is one. So even if you set 0 that will keep one in the memory. – Marcin S. Sep 20 '12 at 03:47
  • is there a way to do what I'm trying to do? – Terence Chow Sep 20 '12 at 04:01
  • I'm not sure if you can do that in an exact way how you described it but maybe this post about adding the number of pages dynamically might be helpful. Please check it and see if you can adapt it to your requirements http://stackoverflow.com/questions/9370961/changing-count-of-viewpager – Marcin S. Sep 20 '12 at 04:11