4

In memory, I have a list of Items, each with a title and a list of 0..N Chunks (which store some information). I know that I am creating this list in memory correctly as I've output the whole structure to the command line.

I have an activity that uses a ViewPager to display this data. Each page of the ViewPager is an Item and it is filled with Fragments that hold information on each Chunk of the Item.

The way I currently have it coded, the Chunks for the first two Items are displayed on the first page under the first Item. When the page is scrolled to the 2nd page, it is empty. When the page is scrolled to the 3rd page (I only have a list of 3 Items for testing right now) it also shows a blank page, however, when the page is returned to the 2nd page, it displays the chunks of the 1st Item. Then, each time there is navigation to the 1st page then the 2nd, the chunks of the 3rd page are newly added to the existing list. If there is navigation from the 2nd page to the 3rd and back, the chunks from the 1st item are newly added to the list. This can be done ad nauseam with an ever growing list. I have no clue why it isn't behaving properly.

Here is my main activity (including the FragmentPagerAdapter):

public class MyActivity extends FragmentActivity {
    MyPagerAdapter mPagerAdapter;
    ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Controller.setup();

        mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());

        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mPagerAdapter);
    }

    public class MyPagerAdapter extends FragmentPagerAdapter {
        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            Fragment fragment = new MyFragment();

            Bundle args = new Bundle();
            args.putInt(MyFragment.POSITION, position);
            fragment.setArguments(args);

            return fragment;
        }

        @Override
        public int getCount(){
            return Controller.getAmount();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return Controller.getItem(position).getTitle();
        }
    }
}

The Controller is very simple and returns the information just as you would expect. Controller.setup() just creates the list of Items.

This is my Item fragment:

public class MyFragment extends Fragment {
    public final static String POSITION = "position";
    private int pos;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        pos = getArguments().getInt(POSITION);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_item, container, false);

        Item item = Controller.getItem(pos);
        Iterator<Chunk> chunks = item.getChunks().iterator();
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();

        while(chunks.hasNext()){
            Chunk chunk = chunks.next();
            ChunkFragment entry = new ChunkFragment();

            Bundle args = new Bundle();         
            args.putString(ChunkFragment.INFO_ARG, chunk.getInfo());
            entry.setArguments(args);

            transaction.add(R.id.container, entry);
        }
        transaction.commit();

        return rootView;
    }
}

And finally my Chunk fragment:

public class ChunkFragment extends Fragment {
    public static final String INFO_ARG = "Info";
    private String mInfo;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        Bundle args = getArguments();
        mInfo = args.getString(INFO_ARG);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //setup view
        ViewGroup rootView;

        rootView = (ViewGroup) inflater.inflate(R.layout.fragment_chunk, container, false);

        TextView infoView = (TextView) rootView.findViewById(R.id.info_text);
        infoView.setText(mInfo);

        return rootView;
    }
}

I know this is a lot of code, but I don't know where the problem is. I've simplified it to the bare minimum, only including operations that could be the source of the problem. I also haven't included my XML layout files, but they have been tested and are working fine.

Jaws212
  • 750
  • 2
  • 7
  • 18
  • On a side note, MyFragment.onCreate() should check to see if savedInstance is null. The contents only need to be added the first time the fragment is created. That's why I was getting duplicates. – Jaws212 Apr 05 '13 at 17:21

1 Answers1

3

I'm not certain about this, but I believe your problem may be related to the difficulties of instantiating Fragments within Fragments in a ViewPager.

You could consider disqualifying this as one of the possibilities by following the guidelines for nesting fragments: this essentially boils down to using getChildFragmentManager() on the Fragment in which you want to add a fragment.

Also, you may want to consider extending the FragmentStatePagerAdapter, which better maintains fragment states between their destruction and recreation.

Paul Lammertsma
  • 37,593
  • 16
  • 136
  • 187
  • So I should create the child fragments from the PagerAdapter directly? – Jaws212 Apr 03 '13 at 19:34
  • Nevermind, I understand what was happening now. And yes, it turns out you were exactly right. Thank you! – Jaws212 Apr 03 '13 at 19:37
  • I was puzzling over your question, too, and then suddenly I recalled having run into a similar problem. I'm very happy to have helped! – Paul Lammertsma Apr 03 '13 at 19:55
  • not working http://stackoverflow.com/questions/31476778/pager-adapter-not-displaying-image-after-getting-from-response-in-fragment/31488006#31488006 – Aditya Jul 18 '15 at 05:33