Where is the best place to assign a host listener within a fragment/child fragment?

Viewed 97

I have a re-useable NumberPickerDialogFragment that can be managed by an activity or a fragment. Every tutorials I've read, assigns the listener in the onAttach(Context) override. Like so:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    try {
        listener = (Listener) context;
    } catch (ClassCastException e) {
        throw new ClassCastException(context.toString()
                + " must implement Listener");
    }
}

Obviously this will work IF and ONLY IF the fragment is hosted by an activity. However, what if the fragment can also be hosted in another fragment? I've read that either the onCreateView or onViewCreated or onActivityCreated can work for this scenario. Like this:

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    try {
        listener = (Listener) getParentFragment();
    } catch (ClassCastException e) {
        throw new ClassCastException(getParentFragment().toString()
                + " must implement Listener");
    }
    return super.onCreateView(inflater, container, savedInstanceState);
}

So both the above codes covers either or, not both situations. Now, since my Fragment extends from DialogFragment, I have the following code:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    Fragment fragment = getParentFragment();

    if (fragment != null) {
        try {
            listener= (Listener) fragment;
        } catch (ClassCastException e) {
            throw new ClassCastException(fragment.toString()
                    + " must implement Listener");
        }
    } else {
        Activity activity = getActivity();
        try {
            listener= (Listener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement Listener");
        }
    }

I'm just concerned that this might not be the best approach, considering all tutorials I've seen does this in the onAttach() override.

My question is then:

  • If onAttach is the best place to assign a host listener where the listener is an Activity, and
  • onCreateView is the best place to assign a host listener where the listener is a parent Fragment,
  • then where is the best place to assign a host listener where the listener could be both an Activity OR a parent Fragment?
1 Answers

After a few months of experimenting and understanding more about Android, I have a solution for this particular conundrum.

The best place for me is to always manage this in the OnAttach() method.

When the OnAttach() is called, this is where I call getParent() to confirm whether this fragment attaches itself directly to the Activity or to a fragment. See example code:

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    if (getParentFragment() == null) {
        try {
            mController = (Controller) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString()
                    + " must implement " + Controller.class.getName());
        }
    } else {
        try {
            mController = (Controller) getParentFragment();
        } catch (ClassCastException e) {
            throw new ClassCastException(getParentFragment().getClass().toString()
                    + " must implement " + Controller.class.getName());
        }
    }
}
Related