5

I have an application that uses ActionBarSherlock and inside the main fragment I have a ViewPager which uses several fragments to display different objects of a list.

Main Fragment:

    public class CollectionDemoFragment extends SherlockFragment {

    DemoCollectionPagerAdapter mDemoCollectionPagerAdapter;
    ViewPager mViewPager;

    public CollectionDemoFragment() {
        setTitle(R.string.title);
        setHasOptionsMenu(true);
    }

    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.demo_fragment, container, false);
        mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getFragmentManager());
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mDemoCollectionPagerAdapter);
        return view;
    }

    @Override
    public void onPause() {
        //This runs when the fragment goes to backstack
        super.onPause();
    }

    @Override
    public void onResume() {
        //This runs when the fragment returns from backstack
        super.onResume();
    }
}

ViewPagerAdapter:

public class DemoCollectionPagerAdapter extends
        FragmentStatePagerAdapter {
    public DemoCollectionPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        Fragment fragment = new DemoObjectFragment();
        Bundle args = new Bundle();
        args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    @Override
    public int getCount() {
        return 100;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "OBJECT " + (position + 1);
    }
}

Inside each of this fragments I can create a new Main fragment with a new list to display in the ViewPager and replace the content with this new fragment.

ViewPager Fragments:

public static class DemoObjectFragment extends Fragment {
    public static final String ARG_OBJECT = "object";

    @Override
    public View onCreateView(LayoutInflater inflater,
            ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(
                R.layout.fragment_collection_object, container, false);
        Bundle args = getArguments();
        ((TextView) rootView.findViewById(android.R.id.text1)).setText(
                Integer.toString(args.getInt(ARG_OBJECT)));
             //Setup components

        return rootView;
    }   

    @Override
    public void setMenuVisibility(final boolean visible) {
        if (visible) {
            //Do something
        }
        super.setMenuVisibility(visible);
    }

    @Override
    public void onPause() {
        //This should run when the fragment goes to backstack
        super.onPause();
    }

    @Override
    public void onResume() {
        //This should run when the fragment returns from backstack
        super.onResume();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.someComponent:
            Fragment newContent = new CollectionDemoFragment();
            switchContent(newContent, true);
            break;
        }
    }

    public void switchContent(Fragment newContent, boolean addToBackStack) {
        if (newContent != null) {
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
            ft.replace(R.id.content_frame, newContent);
            if (addToBackStack) {
                ft.addToBackStack("" + newContent.getId());
            }
            ft.commit();
        }
    }
}

This works ok, until I press back and the previous main fragment returns from the backstack.

The screen is empty (since onCreateView is not called the layout is not inflated), the lifecycle methods from the fragments in the ViewPager are never called either when the main fragment enters the backstack, nor when it returns . The only method called in the fragments of the ViewPager is the setMenuVisibility() so, only the code in there runs.

Anyone knows a way to fix this and why this happens?

Not sure if it matters but I have to support since android 2.3.

Blo
  • 11,903
  • 5
  • 45
  • 99
Mikel
  • 1,581
  • 17
  • 35
  • 1
    Are you using the latest support library revision (v11)? Nested fragments such as you have aren't supported in any previous revision, and so had unpredictable behaviour. – Alex Curran Jan 11 '13 at 12:44
  • And why are there two onCreateView methods in the ViewPager fragments? – Alex Curran Jan 11 '13 at 12:46
  • @Espiandev The two onCreateView methods were a mistake when pasting the code, already edited. I am using support library revision v4, I have v11 but every time i try to add to the project the v4 is added instead. – Mikel Jan 11 '13 at 13:53
  • v4 is what you need, but make sure you have _revision 11 of v4_. Sorry for the ambiguity. – Alex Curran Jan 11 '13 at 19:26
  • Ok then, I do have v4 revision 11 and it does not work. :/ – Mikel Jan 14 '13 at 09:40

1 Answers1

18

When you are creating the view adapter You have to pass the fragment child manager as argument - getChildFragmentManager() instead of getFragmentManager().

Instead of,

 mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getFragmentManager());

you should use,

 mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getChildFragmentManager());
Aishwarya
  • 987
  • 3
  • 10
  • 26
cmota
  • 914
  • 6
  • 7