Passing an Object to Fragment or DialogFragment upon Instantiation

D-Dᴙum picture D-Dᴙum · May 6, 2013 · Viewed 12.6k times · Source

I'm trying to work out the correct way to pass in an Object to a Fragment or DialogFragment without breaking the 'empty constructor' rule.

For example I have created a custom View and for each one I instantiate I want to associate a DiaglogFragment. This DialogFragment will be used to display controls with which the user can alter certain aspects of the custom View it is associated with. Because View is an Object I understand I cannot use setArguments().

I could implement a newInstance(View) method of my DialogFragment i.e. Factory pattern but then what happens if my Fragment is saved by the system and then restored at a later date? As far as I can tell there will be no reference to the View object?

Could someone tell me if I am using Fragments in the wrong way or is there way to achieve passing in an object to the Fragment which will also cope with the system reconstructing it at a later time.

Answer

Karim Aly picture Karim Aly · May 2, 2014

In your DialogFragmnet class, you create two methods:

  1. newInstance to make instance of your DialogFragment

  2. setter to initialize your object

and add setRetainInstance(true); in onCreate

public class YourDialogFragment extends DialogFragment {

    ComplexVariable complexVar;

    public static YourDialogFragment newInstance(int arg, ComplexVariable complexVar) {
        YourDialogFragment frag = new MoveSongDialogFragment();
        Bundle args = new Bundle();
        args.putInt("count", arg);
        frag.setArguments(args);
        frag.setComplexVariable(complexVar);
        return frag;
    }

    public void setComplexVariable(ComplexVariable complexVar) {
        this.complexVar = complexVar;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }
}

then, to show the dialog

FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();

Fragment prev = manager.findFragmentByTag("yourTag");
if (prev != null) {
    ft.remove(prev);
}

// Create and show the dialog.
DialogFragment newFragment = YourFragmentDialog.newInstance(argument, yourComplexObject);
newFragment.show(ft, "yourTag");