5

I'm using a ViewPager with 3 or more Fragments displaying and storing a CustomView as a field.

During the process of the hosting FragmentActivity I need to access and set attributes and fields of the CustomView in order to alter the way they are displayed.

The problem occurs when I need to access not yet instantiated Fragment like the third Fragment in the beginning of the Activity (the first Fragment is default selected and only the next Fragment is instantiated).

My Acticity:

public class VectorProduct extends FragmentActivity {
    ViewPager mViewPager;
    TabsAdapter mTabsAdapter;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pager);

        final ActionBar bar = getSupportActionBar();
        bar.setSubtitle(R.string.bt_dashboard_vector_product);
        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        mTabsAdapter = new TabsAdapter(this, bar, mViewPager);
        mTabsAdapter.addTab(bar.newTab().setText("Vector 1"), VectorFragment.class);
        mTabsAdapter.addTab(bar.newTab().setText("Vector 2"), VectorFragment.class);
        mTabsAdapter.addTab(bar.newTab().setText("Vector 3"), VectorFragment.class);
    }

    public static class TabsAdapter extends FragmentPagerAdapter implements
        ViewPager.OnPageChangeListener, ActionBar.TabListener {
        private final FragmentManager mFragmentManager;
        private final Context mContext;
        private final ActionBar mActionBar;
        private final ViewPager mViewPager;
        private ArrayList<Class<? extends Fragment>> Fragments;

        public TabsAdapter(FragmentActivity activity, ActionBar actionBar,
            ViewPager pager) {
            super(activity.getSupportFragmentManager());
            mFragmentManager = activity.getSupportFragmentManager();
            mContext = activity;
            mActionBar = actionBar;
            mViewPager = pager;
            mViewPager.setAdapter(this);
            mViewPager.setOnPageChangeListener(this);
            setFragments(new ArrayList<Class<? extends Fragment>>());
        }

        public void addTab(ActionBar.Tab tab, Class<? extends Fragment> clss) {
            mActionBar.addTab(tab.setTabListener(this));
            getFragments().add(clss);
            notifyDataSetChanged();
        }

        @Override
        public Fragment getItem(int position) {
            try {
                return Fragments.get(position).newInstance();
            } catch (InstantiationException e) {

            } catch (IllegalAccessException e) {

            }
            return null;
        }

        public Fragment findFragment(int position) {
            String name = "android:switcher:" + mViewPager.getId() + ":" + position;
            Fragment fragment = mFragmentManager.findFragmentByTag(name);
            if (fragment == null) {
                fragment = getItem(position);
            }
            return fragment;
        }
    }
}
user1014917
  • 681
  • 7
  • 13

4 Answers4

3

If you don't mind fragments for each page in the ViewPager being instantiated at all times, then I would change the offscreen page limit, in your onCreateView, after initializing the ViewPager:

mViewPager.setOffscreenPageLimit(2);

I put it to 2 now, since you have 3 tabs. It would be 3 for 4 tabs and so on and so forth. Documentation from Android API: http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit(int)

Changing your offscreen limit to the number of tabs minus 1, means that all neighboring fragments for all tabs are being loaded. This value is 1 by default, so only the closest tabs were loaded.

Be aware that this function has been added quite recently (I think support package v4 release 6), so make sure you have your support package up to date.

zilinx
  • 1,052
  • 8
  • 18
0

You must use nested fragments, to embed a fragment inside a parent fragment. Call in the parent fragment getChildFragmentManager() instead getFragmentManager() to get the working FragmentManager.

Pelanes
  • 3,451
  • 1
  • 34
  • 32
0

Try instantiating the fragment in the onCreateView() method of the individual Fragment class instead of doing that here. Refer http://android.codeandmagic.org/2011/08/android-dynamic-form-fragment/ for more details.

user936414
  • 7,574
  • 3
  • 30
  • 29
0

The problem is that you create fragments on the fly (as needed), but your application logic assumes the fragments exist at all time (or rather: as long as the activity exists). user936414's solution works because this ensures the fragments exist already after instantiating the activity already.

Note that if you only want to show a (bag of) view(s) you might not want to work with fragments at all. You could directly instantiate the views within the ViewPager. This seems especially applicable since you want to access all the page contents at all time. See https://stackoverflow.com/a/8685189/243165 for an example with full code.

Community
  • 1
  • 1
Eric Kok
  • 2,042
  • 3
  • 22
  • 32