在 fragment/child 片段中分配主机侦听器的最佳位置在哪里?

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

我有一个可重复使用的 NumberPickerDialogFragment,它可以由 activity 或片段管理。我读过的每个教程都会在 onAttach(Context) 覆盖中分配监听器。像这样:

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

显然,如果且仅当片段由 activity 托管时,这才有效。但是,如果片段也可以托管在另一个片段中怎么办?我读过 onCreateViewonViewCreatedonActivityCreated 可以工作对于这种情况。像这样:

@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);
}

所以上面的代码都涵盖了其中一种情况,或者不是两种情况。现在,由于我的 Fragment 扩展自 DialogFragment,我有以下代码:

@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");
        }
    }

我只是担心这可能不是最好的方法,考虑到我看到的所有教程都在 onAttach() 覆盖中这样做。

那么我的问题是:

经过几个月的试验和对 Android 的更多了解后,我找到了解决这个特殊难题的方法。

对我来说最好的地方是始终在 OnAttach() 方法中管理它。

调用 OnAttach() 时,我会在此处调用 getParent() 以确认此片段是直接将自身附加到 Activity 还是片段。参见示例代码:

@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());
        }
    }
}