Callback to a Fragment from a DialogFragment Callback to a Fragment from a DialogFragment android android

Callback to a Fragment from a DialogFragment


Activity involved is completely unaware of the DialogFragment.

Fragment class:

public class MyFragment extends Fragment {int mStackLevel = 0;public static final int DIALOG_FRAGMENT = 1;@Overridepublic void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    if (savedInstanceState != null) {        mStackLevel = savedInstanceState.getInt("level");    }}@Overridepublic void onSaveInstanceState(Bundle outState) {    super.onSaveInstanceState(outState);    outState.putInt("level", mStackLevel);}void showDialog(int type) {    mStackLevel++;    FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();    Fragment prev = getActivity().getFragmentManager().findFragmentByTag("dialog");    if (prev != null) {        ft.remove(prev);    }    ft.addToBackStack(null);    switch (type) {        case DIALOG_FRAGMENT:            DialogFragment dialogFrag = MyDialogFragment.newInstance(123);            dialogFrag.setTargetFragment(this, DIALOG_FRAGMENT);            dialogFrag.show(getFragmentManager().beginTransaction(), "dialog");            break;    }}@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {        switch(requestCode) {            case DIALOG_FRAGMENT:                if (resultCode == Activity.RESULT_OK) {                    // After Ok code.                } else if (resultCode == Activity.RESULT_CANCELED){                    // After Cancel code.                }                break;        }    }}}

DialogFragment class:

public class MyDialogFragment extends DialogFragment {public static MyDialogFragment newInstance(int num){    MyDialogFragment dialogFragment = new MyDialogFragment();    Bundle bundle = new Bundle();    bundle.putInt("num", num);    dialogFragment.setArguments(bundle);    return dialogFragment;}@Overridepublic Dialog onCreateDialog(Bundle savedInstanceState) {    return new AlertDialog.Builder(getActivity())            .setTitle(R.string.ERROR)            .setIcon(android.R.drawable.ic_dialog_alert)            .setPositiveButton(R.string.ok_button,                    new DialogInterface.OnClickListener() {                        public void onClick(DialogInterface dialog, int whichButton) {                            getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, getActivity().getIntent());                        }                    }            )            .setNegativeButton(R.string.cancel_button, new DialogInterface.OnClickListener() {                public void onClick(DialogInterface dialog, int whichButton) {                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_CANCELED, getActivity().getIntent());                }            })            .create();}}


TargetFragment solution doesn't seem the best option for dialog fragments because it may create IllegalStateException after application get destroyed and recreated. In this case FragmentManager couldn't find the target fragment and you will get an IllegalStateException with a message like this:

"Fragment no longer exists for key android:target_state: index 1"

It seems like Fragment#setTargetFragment() is not meant for communication between a child and parent Fragment, but rather for communication between sibling-Fragments.

So alternative way is to create dialog fragments like this by using the ChildFragmentManager of the parent fragment, rather then using the activities FragmentManager:

dialogFragment.show(ParentFragment.this.getChildFragmentManager(), "dialog_fragment");

And by using an Interface, in onCreate method of the DialogFragment you can get the parent fragment:

@Overridepublic void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    try {        callback = (Callback) getParentFragment();    } catch (ClassCastException e) {        throw new ClassCastException("Calling fragment must implement Callback interface");    }}

Only thing left is to call your callback method after these steps.

For more information about the issue, you can check out the link:https://code.google.com/p/android/issues/detail?id=54520


I followed this simple steps to do this stuff.

  1. Create interface like DialogFragmentCallbackInterface with some method like callBackMethod(Object data). Which you would calling to pass data.
  2. Now you can implement DialogFragmentCallbackInterface interface in your fragment like MyFragment implements DialogFragmentCallbackInterface
  3. At time of DialogFragment creation set your invoking fragment MyFragment as target fragment who created DialogFragment use myDialogFragment.setTargetFragment(this, 0) check setTargetFragment (Fragment fragment, int requestCode)

    MyDialogFragment dialogFrag = new MyDialogFragment();dialogFrag.setTargetFragment(this, 1); 
  4. Get your target fragment object into your DialogFragment by calling getTargetFragment() and cast it to DialogFragmentCallbackInterface.Now you can use this interface to send data to your fragment.

    DialogFragmentCallbackInterface callback =            (DialogFragmentCallbackInterface) getTargetFragment();callback.callBackMethod(Object data);

    That's it all done! just make sure you have implemented this interface in your fragment.