2

I have finished a simple app to list all products from a mysql database via json. When I click a specific product, it takes me to an activity that displays it's details. Now I changed my app so that when I click a specific product from the list it goes to a 3 tabbed fragment. I have created all the relevant fragments and everything works fine. It only doesn't work when I try to pass the data from the list all products activity to the details fragment activity. How can I pass the data from the main screen which lists all products to the 3 fragments that display the details?

further explanation:

working example without the framents: Main activity displays all products and passes it to details activity upon selecting a single product-> details activity gets data from main activity and displays details

Now I have the main activity which displays all products. Do I pass the data to -> "public class EmpresaDetailsActivity extends FragmentActivity implements ActionBar.TabListener { etc" or do I have to pass it to all other 3 single fragments that I created?

(old way)List all products:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.all_empresas);

        empresaList = new ArrayList<HashMap<String, String>>();

        // Get listview
        ListView lv = getListView();

        // on selecting single empresa
        // launching Empresa Details Screen
        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                // getting values from selected ListItem
                String eid = ((TextView) view.findViewById(R.id.eid)).getText().toString();
                String marca = ((TextView) view.findViewById(R.id.marca)).getText().toString();
                String investimento = ((TextView) view.findViewById(R.id.investimento)).getText().toString();
                String marcatotal = ((TextView) view.findViewById(R.id.marcatotal)).getText().toString();

                // Starting new intent
                Intent in = new Intent(getApplicationContext(),EmpresaDetailsActivity.class);
                // sending data to next activity
                in.putExtra(TAG_EID, eid);
                in.putExtra(TAG_MARCA, marca);
                in.putExtra(TAG_INVESTIMENTO, investimento);
                in.putExtra(TAG_MARCATOTAL, marcatotal);

                // starting new activity and expecting some response back
                startActivity(in);
            }
        });

        // Loading empresa in Background Thread
        new LoadAllEmpresa().execute();
    }

(old way)Details of a single product:

public class EmpresaDetailsActivity  extends Activity {

    // JSON node keys
    private static final String TAG_EID = "eid";
    private static final String TAG_MARCA = "marca";
    private static final String TAG_INVESTIMENTO = "investimento";
    private static final String TAG_MARCATOTAL = "marcatotal";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.details_empresa);

        // getting intent data
        Intent in = getIntent();

        // Get JSON values from previous intent
        String eid = in.getStringExtra(TAG_EID);
        String marca = in.getStringExtra(TAG_MARCA);
        String investimento = in.getStringExtra(TAG_INVESTIMENTO);
        String marcatotal = in.getStringExtra(TAG_MARCATOTAL);

        // Displaying all values on the screen
        TextView lblEid = (TextView) findViewById(R.id.showEid);
        TextView lblName = (TextView) findViewById(R.id.showMarca);
        TextView lblInvestimento = (TextView) findViewById(R.id.showInvestimento);
        TextView lblMarcatotal = (TextView) findViewById(R.id.showMarcaTotal);

        lblEid.setText(eid);
        lblName.setText(marca);
        lblInvestimento.setText(investimento);
        lblMarcatotal.setText(marcatotal);
    }
}

New Details class that has the 3 fragments:

public class EmpresaDetailsActivity extends FragmentActivity implements ActionBar.TabListener {

    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;
    // Tab titles
    private String[] tabs = { "Apresentação", "Ficha Técnica", "Pedir Informação" };

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

        // Initilization
        viewPager = (ViewPager) findViewById(R.id.pager);
        actionBar = getActionBar();
        mAdapter = new TabsPagerAdapter(getSupportFragmentManager());

        viewPager.setAdapter(mAdapter);
        actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Adding Tabs
        for (String tab_name : tabs) {
            actionBar.addTab(actionBar.newTab().setText(tab_name)
                    .setTabListener(this));
        }

        /**
         * on swiping the viewpager make respective tab selected
         * */
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                // on changing the page
                // make respected tab selected
                actionBar.setSelectedNavigationItem(position);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // on tab selected
        // show respected fragment view
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    }

}

TabsPagerAdapter class:

public class TabsPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int index) {

        switch (index) {
        case 0:
            // Top Rated fragment activity
            return new ApresentacaoFragment();
        case 1:
            // Games fragment activity
            return new FichaTecnicaFragment();
        case 2:
            // Movies fragment activity
            return new PedirInformacaoFragment();
        }

        return null;
    }

    @Override
    public int getCount() {
        // get item count - equal to number of tabs
        return 3;
    }

}

example of 1 of the 3 fragments:

public class ApresentacaoFragment extends Fragment {

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

        View rootView = inflater.inflate(R.layout.fragment_apresentacao, container, false);

        return rootView;
    }
}
Acejakk
  • 63
  • 1
  • 9
  • possible duplicate of [How to send data from Activity to Fragment](http://stackoverflow.com/questions/18949746/how-to-send-data-from-activity-to-fragment) – Krylez Oct 07 '14 at 20:32

2 Answers2

6

On your activity onItemClick(), before launching the fragment:

Bundle args = new Bundle();
args.putString(TAG_EID, eid);
args.putString(TAG_MARCA, marca);
args.putString(TAG_INVESTIMENTO, invetstimento);
args.putString(TAG_MARCATOTLA, marcatotal);
yourFragment.setArguments(args);

On your fragment OnCreateView():

Bundle args = getArguments();
String marca = args.getString(TAG_MARCA);
// and so on...

And to be more clear, here is how you should pass data between Activities/Fragments.

  • Activity --> Fragment : Use Bundle and setArguments. (As shown above)
  • Activity --> Activity : Use Intent and putExtra.
  • Fragment --> Activity : Use Interface. Avtivity should implement it, Fragment should call it.

After checking your new code:

  1. Wrap your Strings inside a Bundle and pass it from MainActivity to your EmpresaDetailsActivity.
  2. Fetch it there using getIntent().getExtras().
  3. Change your TabsPagerAdapter to:

    public class TabsPagerAdapter extends FragmentPagerAdapter {
    
    private Bundle args;
    
    public TabsPagerAdapter(FragmentManager fm, Bundle args) {
        super(fm);
        this.args = args;
    }
    
    @Override
    public Fragment getItem(int index) {
    
    switch (index) {
    case 0:
        // Top Rated fragment activity
        ApresentacaoFragment apresentacaoFragment = new ApresentacaoFragment();
        apresentacaoFragment.setArguments(args);
        return apresentacaoFragment;
    case 1:
        // Games fragment activity
        // do the same as above with your Games fragmnet class
    case 2:
        // Movies fragment activity
        // ...
    }
    
    return null;
     }
    
     @Override
    public int getCount() {
        // get item count - equal to number of tabs
        return 3;
    }   
    }
    
    1. When instantiate the adapter, pass the bundle to its constructor.
    2. In your fragment classes use getArguments() to fetch the bundle and you're done.
Alon Levanon
  • 691
  • 5
  • 18
  • Just to clarify ( and because I just starting using fragments to get myself up to date ) when I have the list of all products in my activity I will create that bundle in "onItemClick()". Then on my Details fragment ( which has 3 tabbs (they are sub-fragments?) ) I will put the bundle in "OnCreateView()", which will pass the data to all my 3 tabs right? – Acejakk Oct 07 '14 at 20:35
  • By saying 3 tabs fragment you mean 3 fragments and one TabActivity? – Alon Levanon Oct 07 '14 at 20:42
  • I have edited the answer, maybe it will be more clear. – Alon Levanon Oct 07 '14 at 20:46
  • I mean switch between tabs in the action bar which correspond to a fragment each – Acejakk Oct 07 '14 at 20:51
  • Please show your last code (the one with the fragments) – Alon Levanon Oct 07 '14 at 20:57
  • This is the new activity that has 3 fragments: "public class EmpresaDetailsActivity extends FragmentActivity implements ActionBar.TabListener {" – Acejakk Oct 08 '14 at 13:17
  • Please edit your question and add the new code there, not in comments. – Alon Levanon Oct 08 '14 at 13:37
  • So, to finalize this solution, I have to edit the section of EditDetailsActivity after I get the intent and the JSON values like before, but instead of displaying the values I create a new bundle with the Strings I got from my main activity correct? – Acejakk Oct 08 '14 at 14:36
  • Yes, and pass the bundle to the adapter's constructor and then to the other fragments. – Alon Levanon Oct 08 '14 at 14:40
  • I get all sorts of errors in step 1,2,4 and 5. I bet I am not working with the bundle correctly. Could you tell me where to change things from my original code like in step 3? Sorry for the trouble :\ – Acejakk Oct 08 '14 at 15:05
  • We can't move to chat conversation because you dont have enough reputation points. check your mail. – Alon Levanon Oct 08 '14 at 15:11
  • This guy is the best. The aswer is 100% correct. Thank you for all the help – Acejakk Oct 08 '14 at 16:59
0

Since EmpresaDetailsActivity is the Activity that is containing your three Fragments I think is a good practice to pass the data from MainActivity to EmpresaDetailsActivity and then from there pass it to the Fragments. That way you are respecting hierarchy.

To pass values to a Fragment from an Activity you can do as follows:

1) In each Fragment class define a static method called newInstance, where you will get all the values

public static YourFragmentClass newInstance(int myValue, int MyValue2) {
    // You can add as many values as you need to initialize your fragment
    YourFragmentClass fragment = new YourFragmentClass();
    Bundle args = new Bundle();
    args.putInt("value_key", myValue);
    args.putInt("value_key2", myValue2);
    fragment.setArguments(args);
    return fragment;
}

2) In your TabAdapter when your create the Fragments, just replace your Fragment declaration with

YourFragmentClass.newInstance(value1, value2);

3) On the onCreate method of each Fragment retrieve the values that you passed:

@Override
public View onCreate(Bundle savedInstanceState) {

    int myValue = getArguments().getInt("value_key"));
    int myValue2 = getArguments().getInt("value_key2"));
}

That way you have a cleaner way to initialize your Fragments

Carlos J
  • 2,965
  • 4
  • 17
  • 28
  • So, in my 3 fragments I implement step 1 and 3? what about the class that implements the 3 fragments and my main class? – Acejakk Oct 08 '14 at 13:28
  • Leave your main class as it is, and the one that implements the 3 fragments should be where you do step 2, specifically in the TabsPagerAdapeter under the `getItem` method – Carlos J Oct 08 '14 at 14:21
  • So I left alone my AllEmpresaActivity and EmpresaDetailsActivity. How am I getting the values from AllEmpresaActivity in TabsPagerAdapter? – Acejakk Oct 08 '14 at 15:03