[android] Passing an Object from an Activity to a Fragment

I have an Activity which uses a Fragment. I simply want to pass an object from this Activity to the Fragment.

How could I do it? All the tutorials I've seen so far where retrieving data from resources.

EDIT :

Let's be a bit more precise:

My Activity has a ListView on the left part. When you click on it, the idea is to load a Fragment on the right part.

When I enter this Activity, an Object Category is given through the Intent. This Object contains a List of other Objects Questions (which contains a List of String). These Questions objects are displayed on the ListView. When I click on one item from the ListView, I want to display the List of String into the Fragment (into a ListView).

To do that, I call the setContentView() from my Activity with a layout. In this layout is defined the Fragment with the correct class to call. When I call this setContentView(), the onCreateView() of my Fragment is called but at this time, the getArguments() returns null.

How could I manage to have it filled before the call of onCreateView() ? (tell me if I'm not clear enough)

Thanks

This question is related to android

The answer is


You should create a method within your fragment that accepts the type of object you wish to pass into it. In this case i named it "setObject" (creative huh? :) ) That method can then perform whatever action you need with that object.

MyFragment fragment;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

        if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
            fragment = new MyFragment();
            getSupportFragmentManager().beginTransaction().add(android.R.id.content, detailsFragment)
                    .commit();
        } else {
           fragment = (MyFragment) getSupportFragmentManager().findFragmentById(
                    android.R.id.content);
        }


        fragment.setObject(yourObject); //create a method like this in your class "MyFragment"
}

Note that i'm using the support library and calls to getSupportFragmentManager() might be just getFragmentManager() for you depending on what you're working with


In your activity class:

public class BasicActivity extends Activity {

private ComplexObject co;

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

    co=new ComplexObject();
    getIntent().putExtra("complexObject", co);

    FragmentManager fragmentManager = getFragmentManager();
    Fragment1 f1 = new Fragment1();
    fragmentManager.beginTransaction()
            .replace(R.id.frameLayout, f1).commit();

}

Note: Your object should implement Serializable interface

Then in your fragment :

public class Fragment1 extends Fragment {

ComplexObject co;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Intent i = getActivity().getIntent();

    co = (ComplexObject) i.getSerializableExtra("complexObject");

    View view = inflater.inflate(R.layout.test_page, container, false);
    TextView textView = (TextView) view.findViewById(R.id.DENEME);
    textView.setText(co.getName());

    return view;
}
}

Passing arguments by bundle is restricted to some data types. But you can transfer any data to your fragment this way:

In your fragment create a public method like this

public void passData(Context context, List<LexItem> list, int pos) {
    mContext = context;
    mLexItemList = list;
    mIndex = pos;
}

and in your activity call passData() with all your needed data types after instantiating the fragment

        WebViewFragment myFragment = new WebViewFragment();
        myFragment.passData(getApplicationContext(), mLexItemList, index);
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(R.id.my_fragment_container, myFragment);
        ft.addToBackStack(null);
        ft.commit();

Remark: My fragment extends "android.support.v4.app.Fragment", therefore I have to use "getSupportFragmentManager()". Of course, this principle will work also with a fragment class extending "Fragment", but then you have to use "getFragmentManager()".


Get reference from the following example.

1. In fragment: Create a reference variable for the class whose object you want in the fragment. Simply create a setter method for the reference variable and call the setter before replacing fragment from the activity.

 MyEmployee myEmp;
 public void setEmployee(MyEmployee myEmp)
 {
     this.myEmp = myEmp;
 }

2. In activity:

   //we need to pass object myEmp to fragment myFragment

    MyEmployee myEmp = new MyEmployee();

    MyFragment myFragment = new MyFragment();

    myFragment.setEmployee(myEmp);

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.main_layout, myFragment);
    ft.commit();

To pass an object to a fragment, do the following:

First store the objects in Bundle, don't forget to put implements serializable in class.

            CategoryRowFragment fragment = new CategoryRowFragment();

            // pass arguments to fragment
            Bundle bundle = new Bundle();

            // event list we want to populate
            bundle.putSerializable("eventsList", eventsList);

            // the description of the row
            bundle.putSerializable("categoryRow", categoryRow);

            fragment.setArguments(bundle);

Then retrieve bundles in Fragment

_x000D_
_x000D_
       // events that will be populated in this row_x000D_
        mEventsList = (ArrayList<Event>)getArguments().getSerializable("eventsList");_x000D_
_x000D_
        // description of events to be populated in this row_x000D_
        mCategoryRow = (CategoryRow)getArguments().getSerializable("categoryRow");
_x000D_
_x000D_
_x000D_


This one worked for me:

In Activity:

User user;
public User getUser(){ return this.user;}

In Fragment's onCreateView method:

User user = ((MainActivity)getActivity()).getUser(); 

Replace the MainActivity with your Activity Name.


If the data should survive throughout the application lifecycle and shared among multiple fragments or activities, a Model class might come into consideration, which has got less serialization overhead.

Check this design example