user3860911
user3860911

Reputation: 139

How to pass data between fragments when using tabs and onTabSelected()?

This tutorial refers to the communicating between fragments but doesn't do it for tabs. I want to send data between from my "Daycare" fragment which is a tab to my "You" fragment which is also a tab. I've been stuck for a week on this. I don't really know how to combine the concept of interfaces with android tabbed fragments and data from asynctasks.

I have created an interface in my Daycare fragment. I want to send the String "daycarename" to the "you" fragment with the help of the "passparam" method. From what I understood it needs to somehow pass through the MainActivity which implements my TabClickedListener interface. How do I pass it from the MainActivity back to the other fragment?

public class MainActivity extends Activity implements ActionBar.TabListener, DaycareFragment.TabClickedListener {

    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 {

    public SectionsPagerAdapter(FragmentManager fm) {

        super(fm);
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:

                return new YouFragment();
            case 1:

                return new DaycareFragment();
            case 2:

                return new ThirdFragment();

        }

        return null;
    }

    @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 getString(R.string.title_section3).toUpperCase(l);
            case 1:
                return getString(R.string.title_section1).toUpperCase(l);
            case 2:
                return getString(R.string.title_section2).toUpperCase(l);

        }
        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;
        }
    }
    @Override
    public void passParam(String var) {
        Toast.makeText(this, "Clicked " + var, Toast.LENGTH_LONG).show();

    }
}

I am implementing an interface in my ListFragment:

public class DaycareFragment extends ListFragment {

    TabClickedListener listener;

    public interface TabClickedListener {
        public void passParam(String var);
    }
String email;
    UserFunctions userFunctions;
    Boolean owner;
@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_daycare, container, false);
        movies = new ArrayList<HashMap<String, String>>();

        userFunctions = new UserFunctions();
        HashMap map = new HashMap();
        map = userFunctions.getdauser(getActivity());
        email = (String) map.get("email");

        new GetDaDaycares().execute();

        return rootView;
    }
class GetDaDaycares extends AsyncTask<String, String, String>{

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }


        @Override
        protected String doInBackground(String... args) {

            String city = "london";
            try {

                List<NameValuePair> params = new ArrayList<NameValuePair> ();
                params.add(new BasicNameValuePair("city", city));

                @SuppressWarnings("unused")
                JSONObject json = parser.makeHttpRequest(getdaycare, params);
                jArray = json.getJSONArray("lTable");

                for (int i =0; i<jArray.length();i++){

                    JSONObject c = jArray.getJSONObject(i);
                    String daycarename = c.getString("daycarename");

                    HashMap<String, String> map = new HashMap<String, String>();
                    map.put("daycarename", daycarename);
                    movies.add(map);

                }

            } catch(JSONException e) {

                e.printStackTrace();
            }
            return null;

        }

        protected void onPostExecute(String zoom){
            pDialog.dismiss();

            getActivity().runOnUiThread(new Runnable() {
                public void run() {


                    ListAdapter adapter = new SimpleAdapter(getActivity(), movies,
                            R.layout.list, new String[] {"daycarename"},
                            new int[]{R.id.textView1});

                    setListAdapter(adapter);
                    ListView lv = getListView();
                    lv.setOnItemClickListener(new OnItemClickListener(){

                        @Override
                        public void onItemClick(AdapterView<?> parent, View view, int position,
                                                long id) {

                            String daycarename =movies.get(position).get("daycarename");

                        }

                    });


                }
            });
        }

    }

}

Upvotes: 0

Views: 1003

Answers (2)

Xcihnegn
Xcihnegn

Reputation: 11597

In your Activity:

public void passStrToYou(String daycarename)
{
   FragmentManager fm = getFragmentManager();               
   Fragment youFrag = (YouFragment)fm.FragmentManager fm.findFragmentById(R.id.youFragment);

   //call mathod 'setDayCareName' in 'you' fragment
   youFrag.setDayCareName(daycarename);
}

Hope this help!

Upvotes: 1

eimmer
eimmer

Reputation: 1709

If this was my problem (which it has been) I would have a central object that is in charge of 'sharing' data between the fragments.

The implementation usually seems to follow 1 of 2 paths: One, create a singleton that any object can get an instance of, or two, the activity initializes the single instance of an object and passes it to each fragment upon their initialization.

Fragments (or an AsyncTask) would then update and pull data from that central object via the Observer Pattern or on display, however you'd want.

p.s. If you are going to have an AsyncTask in a fragment, you will want to implement a strategy for insuring your UI is not dead when it finishes. Otherwise you can throw an exception.

p.p.s onPostExecute runs on the UI thread by default.

Upvotes: 1

Related Questions