10

I am using the built-in Navigation drawer activity with three fragment menus, and I want to communicate over those fragments, meaning to pass data from one to another. And I found there are three possible ways to communicating with fragments. Also, I have understood clearly that the fragments never communicate directly.

  • Using Interface
  • Global class (extends the Application class)
  • finally Using bundles

What is the best way to communicate with fragments? Currently I am using the second method in which I put(getter&setter class) all those objects to the `Globalized objects which extends the Application class. Is this the right approach or not?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Narandhran Thangavel
  • 1,392
  • 1
  • 12
  • 20

6 Answers6

21

You can implement Serializable in your Object class and then pass it simply using bundles. I'm assuming you're launching the second_fragment from your first_fragment.

In your first Fragment:

FragmentTransaction ft =  getActivity().getSupportFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
Fragment2 fragment2 = new Fragment2();

Bundle bundle = new Bundle();
YourObj obj = SET_YOUR_OBJECT_HERE;
bundle.putSerializable("your_obj", obj);
fragment2.setArguments(bundle);
ft.replace(android.R.id.content, fragment2);
ft.addToBackStack(null);
ft.commit();

In Fragment two:

Bundle bundle = getArguments();
YourObj obj= (YourObj) bundle.getSerializable("your_obj");

To Serialize your object, simply implement Serializable in your Object class.

If your Object class is YourObj.class

public class YourObj implements Serializable {
    int id;
    String name;

    // GETTERS AND SETTERS
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rachit
  • 3,173
  • 3
  • 28
  • 45
7

Objects can be passed among fragment and Activities by making the model class Serializable or Parcelable.

Parcelable is an Android class and can support more complex serialization of classes. Check the implementation of Parceble class here: http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/

Serializable is a Java class and is good for small objects. For Serializable visit here: https://developer.android.com/reference/java/io/Serializable.html

Suppose your model class is NewObject then use following in your fragment class:

Fragment fragment = new Fragment();
NewObject newObject = new NewObject();

Bundle bundle = new Bundle();
bundle.putParcelable("Object", newObject);
fragment.setArguments(bundle); 

To get it from bundle in another fragment use in your onCreate function:

NewObject newObject = (NewObject) bundle.getParcelable("Object");
nnn
  • 980
  • 6
  • 13
5

Data Holder class:

    public class DataHolder implements Serializable{

        private String name,id;

        public DataHolder(String id, String name) {
            this.id = id;
            this.name = name;

        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

FragmentA:

    DataHolder dataholder=new DataHolder("1","TestName");
    Bundle bundle=new Bundle();
    bundle.putSerializable("obj",dataholder);

    Fragment fragment=new FragmentB();
    fragment.setArguments(bundle);
    fragmentManager = getActivity(). getSupportFragmentManager();
    fragmentTransaction = fragmentManager .beginTransaction();
    fragmentTransaction.add(R.id.container, fragment);
    fragmentTransaction.commit();

FragmentB:

   DataHolder dataholder = (DataHolder)getArguments().getSerializable(obj);  
Komal12
  • 3,340
  • 4
  • 16
  • 25
  • This answer appears to be missing its educational explanation. Please do not snippet-dump in the Stack Exchange Network. Every answer should include some plain English explanation to better education/empower the asker, future researchers, ...and the AI that will eventually rule the web. – mickmackusa May 23 '23 at 21:18
2

In your Activity hosting those fragments, define a variable,

public class HomeActivity{

    public User mUser;
    ...
}

Now, In your fragment, when you get response from your Api, initialise variable User in Activity as below:

@Override
public void onClick(View view) {
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, getString(R.string.RESTAPI_URL), null, new Response.Listener<JSONObject>() {

        @Override
        public void onResponse(JSONObject response) {
            Log.d("Response: ",response.toString());
            Gson gson = new Gson();
            User user = gson.fromJson(String.valueOf(response),User.class);

            // initialise User variable in Home Activity
            ((HomeActivity)getActivity()).mUser = user;
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.d("ErrorResponse: ",error.toString());
        }
    });
      RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
      requestQueue.add(jsonObjectRequest);

}

Assuming, your User class implements Parcelable interface, and if not, then just make that class Parcelable. This works same as Serializable in Java, but Parcelable is optimized for Android.

Lastly, when you load second fragment, simply pass User object to second Fragment as below:

SecondFragment secondFragment = new SecondFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("ARG_USER", user);
secondFragment.setArguments(bundle);
//...code for loading second fragment
Chintan Soni
  • 24,761
  • 25
  • 106
  • 174
  • 3
    Why not just call the user variable in the second fragment the same way it was initialized in the 2nd fragment? I've actually done something like `((HomeActivity)getActivity()).mUser = user` in fragments before & it seems to work fine. But is this really ok? I like it cause it's dead simple. – Aba Sep 25 '17 at 12:28
1

When you need limited data to pass between fragments you can use Bundle Instance. If you having complex objects to pass you prefer interface instead other ways. you can also check the link for reff

Community
  • 1
  • 1
Vijay
  • 227
  • 3
  • 18
1

You can try this way.. In your first fragment

Outlet outlet=New Outlet;
Bundle bundle = new Bundle();
bundle.putSerializable("outlet",outlet);
Fragment frag=null;
frag=new Outlet_Edit();
if(frag!=null){
   frag.setArguments(bundle);
   FragmentManager fragmentManager=getActivity().getSupportFragmentManager();
   FragmentTransaction ft=fragmentManager.beginTransaction();
   ft.replace(R.id.sacreenarea,frag);
   ft.commit();
}

In your Second Fragment

//second Fragmnet
Outlet editing_outlet=(Outlet) getArguments().getSerializable("outlet");
Log.d("Editing Outlet",editing_outlet.toString());

And Object should be like this way..

public class Outlet implements Serializable {
String id;
String shopname;
String shopowner;
String address;
String contact;
String marketid;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getShopname() {
    return shopname;
}

public void setShopname(String shopname) {
    this.shopname = shopname;
}

public String getShopowner() {
    return shopowner;
}

public void setShopowner(String shopowner) {
    this.shopowner = shopowner;
}

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

public String getContact() {
    return contact;
}

public void setContact(String contact) {
    this.contact = contact;
}

public String getMarketid() {
    return marketid;
}

public void setMarketid(String marketid) {
    this.marketid = marketid;
}

@Override
public String toString() {
    return "Outlet{" +
            "id='" + id + '\'' +
            ", shopname='" + shopname + '\'' +
            ", shopowner='" + shopowner + '\'' +
            ", address='" + address + '\'' +
            ", contact='" + contact + '\'' +
            ", marketid='" + marketid + '\'' +
            '}';
}

}
Muhaiminur Rahman
  • 3,066
  • 20
  • 27