Returning the execution result from DialogFragment to Fragment bypassing Activity

Introduction


In this post, I will show how you can pass events from DialogFrament to the calling Fragment bypassing Activity.

The official Dialogs Guide has a PassingEvents section . It tells how to return the result of DialogFragment to the calling Activity. An additional interface is created for this. Activity implements this interface, and DialogFrament has a link to Activity.

If the initiator of the DialogFragment call is another Fragment, then in this approach we will have to first send the result to the Activity, and then from the Activity to the Fragment interested in the data. Hence the cons:
  • Activity knows about the details of the fragment implementation (today this is an additional dialogue, and tomorrow we can implement everything on one fragment);
  • additional code (more code = more opportunities for errors).


Fortunately, the Fragment class has 3 methods that allow you to implement the transfer of events from one fragment to another fragment bypassing Activity. It:

The essence of the method


The calling fragment:
  • using setTargetFragment sets itself as targetFrament and sets requestCode;
  • implements the onActivityResult method in which it processes requestCode and resultCode, and also has access to additional data through intent.

The called fragment:
  • c using getTargetFrament gets a link to the calling fragment;
  • using getTargetRequestCode it gets the code with which it was called;
  • calls onActivityResult of the calling fragment and passes the results of its execution through resultCode and Intent (for additional).

Below is a sample code. For simplicity, I left only parts relevant to the article.

The calling fragment:

public class HostFragment extends Fragment {
    private static final int REQUEST_WEIGHT = 1;
     private static final int REQUEST_ANOTHER_ONE = 2;
     public void openWeightPicker() {
        DialogFragment fragment = new WeightDialogFragment();
        fragment.setTargetFragment(this, REQUEST_WEIGHT);
        fragment.show(getFragmentManager(), fragment.getClass().getName());
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case REQUEST_WEIGHT:
                         int weight = data.getIntExtra(WeightDialogFragment.TAG_WEIGHT_SELECTED, -1)
                         //используем полученные результаты
                         //...
                         break;
                    case REQUEST_ANOTHER_ONE:
                        //...
                         break;
                //обработка других requestCode
            }
            updateUI();
        }
    }
}

The called fragment:

public class WeightDialogFragment extends DialogFragment {
     //тэг для передачи результата обратно
    public static final String TAG_WEIGHT_SELECTED = "weight";
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        LayoutInflater inflater = getActivity().getLayoutInflater();
        View view = inflater.inflate(..., null);
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setView(view)
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                             //отправляем результат обратно
                        Intent intent = new Intent();
                        intent.putExtra(TAG_WEIGHT_SELECTED, mNpWeight.getValue());
                        getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, intent);
                    }
                });
        return builder.create();
    }
}

Conclusion


The disadvantages listed at the beginning of the article are absent in this approach. Only two interacting elements know each other. For the rest, these are already unknown implementation details.

I would like to know about this implementation option while studying the official dialog guide. I found out later thanks to StackOverflow .

Also popular now: