Tester101
Tester101

Reputation: 8172

How can I pass data between fragments when using tab navigation?

I'm using tab navigation in my app. Each tab has a form that preforms similar tasks, so I'm using the same fragment but simply hiding/showing bits of it. It appears that the ViewPager is instantiating 3 different copies of the fragment, and then switching between them when the user changes tabs. Since all the fragments are the same, I'd like to pass the state of the fields between them. This way when a user changes to a different tab, the information they filled in on the previous tab is present on the new tab.

Is there a preferred method to passing data in this way?

The dumbed down code looks like this...

public class MainActivity extends Activity implements ActionBar.TabListener {

    SectionsPagerAdapter mSectionsPagerAdapter;
    ViewPager mViewPager;

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

        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager(), this);

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

         mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });

         for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            actionBar.addTab(
                actionBar.newTab()
                    .setText(mSectionsPagerAdapter.getPageTitle(i))
                    .setTabListener(this));
        }
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
        mViewPager.setCurrentItem(tab.getPosition());
    }

    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        private Context context;

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        public SectionsPagerAdapter(FragmentManager fm, Context context) {
            super(fm);
            this.context = context;
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {
                case 0:
                    return getResources().getString(R.string.tab_one_title);
                case 1:
                    return getResources().getString(R.string.tab_two_title);
                case 2:
                    return getResources().getString(R.string.tab_three_title);
            }
            return null;
        }
    }

    public class MainFragment extends Fragment {

        private static final String ARG_SECTION_TYPE = "section type";

        public MainFragment(){}

        public MainFragment(int sectionNumber) {
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_TYPE, sectionNumber);
            setArguments(args);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);

            //setup the view
            switch(getArguments().getInt(ARG_SECTION_TYPE)) {
                //hide or show fields based on page number.
            }

            return rootView;
        }
    }
}

If the user modifies a field on page 1, i'd like the information to also show up on page 2, and page 3. What's the preferred method to accomplish this?

Upvotes: 0

Views: 662

Answers (1)

NameSpace
NameSpace

Reputation: 10177

  1. Data-Push Method: LocalBroadcastManager

Each fragment registers a broadcastReceiver, and when data changes broadcast it to all registered receivers. It's the sender of the data that decides when the receiving objects are updated.

For an example of implementing a LocalBroadcastManager: how to use LocalBroadcastManager?

  1. Data-Pull Method: Central repository.

Send the data to an intermediary object (the central repository) to store the data. Then each fragment can poll the object whenever it needs to be updated with the latest data.

In this case, the activity would reference the object, and each fragment would call to the repository by ((MyInterface) getActivity).mDataObject.data....

Upvotes: 1

Related Questions