16

I have a ViewPager with 10 pages. When I start the last (10th) page onCreateView() method of my fragment is called. When I swipe to the 9th page onCreateView() is called also. But when I back to the 10th page onCreateView() isn't called. What's wrong?

Bakus123
  • 1,339
  • 5
  • 18
  • 37

6 Answers6

22

Try Extending FragmentStatePagerAdapter

Vinay
  • 1,458
  • 14
  • 23
3

That is because a FragmentPagerAdapter keeps in memory every fragment. Hence, when you visit the first time the fragment, onCreate will be invoked but the second time Android will looking for in memory, so it not need invoke onCreate.

If you need run the code in OnCreate every time fragment is displayed, you should move it to getItem(int id)

See offical documentation: http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html

Fran b
  • 2,686
  • 6
  • 28
  • 53
  • Thank you, but I added Log.i("hello", "hello" + id); to getItem method, and this log I only see when I start the viewpager. When I swipe between pages it doesn't invoke. – Bakus123 Aug 29 '14 at 19:06
  • Ok, try to override onResume method. – Fran b Aug 29 '14 at 19:09
  • onResume for Fragment or FragmentPagerAdapter ? – Bakus123 Aug 29 '14 at 19:13
  • onResume for Fragment, or if you need call that code in OnCreate and in OnResume, you can write a separate function and invoke it from that two methods. – Fran b Aug 29 '14 at 19:22
2

Nothing is wrong. The ViewPager already has the page, and so it does not need to create it.

CommonsWare
  • 910,778
  • 176
  • 2,215
  • 2,253
  • 3
    How can I do it when any of method (onStart, OnCreate, onCreateView) isn't inoke? – Bakus123 Aug 29 '14 at 19:19
  • @Bakus123: One possibility is to add an `OnPageChangeListener` to the `ViewPager`, so you know when it changes pages. Or, just update the page when the data changes, rather than waiting for the user to swipe to it, for all pages that have been created so far. – CommonsWare Aug 29 '14 at 19:21
  • @Bakus123: You will need to keep track of which fragments exist and belong to which positions. Then, you can call some method on your fragments to tell them to update based upon the page change. – CommonsWare Aug 29 '14 at 19:39
2

I had the same problem, my solution was to assign again the adapter of the ViewPager instance, just like:

pager.setAdapter(adapter);

This causes a restart of the "mItems" property from the viewPager and removes the cache.

But I don't know if it's a safe solution

1

You can call the adapter getItem from onPageSelect, which is called also on swipes, and place your code inside the getItem, or even in the onPageSeelect itself.

Zvi
  • 1,858
  • 2
  • 19
  • 32
0

CommonWare's answer is the best and works like charm: simple add OnPageChangeListener to your ViewPager item, something like this:

ViewPager     viewPager    = null;
PagerAdapter  pagerAdapter = null;

//Some code come here...

pagerAdapter = new PagerAdapter(); //Or any class derived from it
viewPager    = (ViewPager)findViewById(R.id.container);//Connect it to XML
viewPager.setAdapter (mPagerAdapter); //Connect the two

//Next two lines are simply for fun...
//viewager.setPageTransformer(true, new DepthPageTransformer());
//viewPager.setPageTransformer(true, new PaymentZoomOutPageTransformer());

 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }
        //This is the right place to connect the pages with a data struct!!!
        @Override
        public void onPageSelected(int position) {
            // Here you can connect the current displayed page with some data..
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

 //Here use the inflater to add views/pages
 //Don't forget to do:
 pagerAdapter.notifyDataSetChanged();
 //When you're done...
JamesC
  • 304
  • 3
  • 7