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



我有一个可重用的NumberPickerDialogFragment,可以由活动或片段管理。我读过的每个教程,都会在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");
}
}

显然,这将在 IF 且仅当片段由活动托管时才有效。但是,如果片段也可以托管在另一个片段中怎么办?我读过onCreateView或onViewCreatedonActivityCreated都可以用于这种情况。喜欢这个:

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

因此,上述两个代码都涵盖了其中一种情况,而不是两种情况。现在,由于我的片段是从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((覆盖中这样做。

那么我的问题是:

  • 如果onAttach是分配主机侦听器的最佳位置,其中侦听器是活动,并且
  • onCreateView是分配主机侦听器的最佳位置,其中侦听器是父片段
  • 那么分配主机侦听器的最佳
  • 位置在哪里,其中侦听器既可以是活动也可以是父片段

经过几个月的实验和对Android的更多了解,我有一个解决这个特殊难题的解决方案。

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

当调用 OnAttach(( 时,我调用 getParent(( 来确认这个片段是直接附加到活动还是片段。请参阅示例代码:

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