如何保留从片段打开的自定义对话框的监听器?

我遇到了一些障碍。 我有一个非常类似于以下所述的场景: DialogFragment – 屏幕旋转后保留监听器

build议的解决scheme适用于作者,因为他的对话框是从一个活动中调用的。 我的情况是完全一样的,但我的自定义对话框是从一个片段调用,而不是一个活动。 (IE Activity-> Fragment-> Dialog)

我实现了相同的解决scheme(在调用Fragment的onResume中设置监听器),但在这种情况下不起作用。

似乎正在发生的事情是,当屏幕旋转,Android杀死对话框和片段。 然后在那个命令中重新创build它们。 所以当我的自定义对话框上调用了onCreateDialog时,包含的Fragment还没有被重新创build,所以对于侦听器来说,它设置为正和负的button。

有没有人知道这个方法?

如果有人认为这是必要的,我可以发布代码,但它与链接线程上的代码非常相似。

用代码更新:

public class RecipeDetailEditFragment extends SherlockFragment implements DialogInterface.OnClickListener { private EditStepFragmentDialog stepDialog; private Recipe newRecipe; //main data object implements parcelable ... public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... stepDialog = EditStepFragmentDialog.newInstance(newRecipe); //I've also tried passing 'this' into the newInstance constructor and //setting the listener there, but that doesn't work either } public void onResume() { stepDialog.setListener(this); super.onResume(); } ... } public class EditStepFragmentDialog extends DialogFragment { private DialogInterface.OnClickListener ocl; private static final String ARG_RECIPE = "recipe"; private Recipe recipe; public EditStepFragmentDialog() {} public static EditStepFragmentDialog newInstance(Recipe rec) { //(Recipe rec, DialogInterface.OnClickListener oc) as mentioned doesn't work. EditStepFragmentDialog dia = new EditStepFragmentDialog(); Bundle args = new Bundle(); args.putParcelable(ARG_RECIPE, rec); //dia.setListener(oc); return dia; } public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder adb = new AlertDialog.Builder(getActivity()); if (getArguments().containsKey(ARG_RECIPE)) { recipe = (Recipe) getArguments().getParcelable(ARG_RECIPE); } ... adb.setPositiveButton("Done", ocl); adb.setNegativeButton("Cancel", ocl); ... return adb.create(); } public void setListener(DialogInterface.OnClickListener cl) { ocl = cl; } } 

Solutions Collecting From Web of "如何保留从片段打开的自定义对话框的监听器?"

我浏览了所有讨论的链接上的所有选项,没有任何解决scheme为我工作。 进一步Googlesearch之后,我也尝试了一些额外的选项,如get / setTargetFragment和FragmentManager.put / getFragment。 这些也不适合我。 然后我再看看:

http://developer.android.com/training/basics/fragments/communicating.html

他们在哪里具体说“两个碎片不要直接交stream”。 我认为这是事实certificate是真实的情况之一。

我最终实现了提供的build议callback机制,并以此结束:

在DialogFragment中:

 public interface OnEditStepDialogListener { public void onEditStepDialogPositive(int pos, String description); } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mCallback = (OnEditStepDialogListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnEditStepDialogListener"); } } 

在主持活动:

 public class MyActivity extends SherlockFragmentActivity implements EditStepFragmentDialog.OnEditStepDialogListener { ... @Override public void onEditStepDialogPositive(int pos, String desc) { FragmentManager fm = getSupportFragmentManager(); RecipeDetailEditFragment ef = (RecipeDetailEditFragment)fm.findFragmentByTag(RecipeDetailEditFragment.TAG); ef.applyStepEdit(pos, desc); } 

在FragmentDialog的片段中:

 public static final String TAG = "tag1"; public void applyStepEdit(int pos, String description) { ... } 

这完美的工作,如果打开方向更改和编辑完成,它实际上触发最终的function,我需要在调用片段运行,而不是崩溃或不做任何事情(空监听器)。

向您的活动进行报告并创build对话框会是一场灾难吗?

我刚刚检查我的代码,看看我在做什么,因为我没有遇到这个问题。 我认为这是这样的:

 - MyActivity | ---- MapsFragmet (for example) | ---- DirectionsModule (simple class that is handed Context) | ---- PointsOfInterestModule (simple class that is handed Context) 

因此,利用这种构造,活动纯粹使用片段来显示地图,但是可以根据调用哪个模块将其用于方向目的或兴趣点。

现在,当模块遇到问题或者需要用户交互时,它会报告给MyActivity,然后例如显示一个DialogFragment。

想给一个更好的答案,因为我不明白为什么你不应该能够从另一个片段内调用DialogFragment,并期望一个不错的行为。

为了以防万一,你有没有设置setRetainInstance(true)你片段?

编辑:

好吧,我刚刚回顾了你刚刚提交的代码,这是我的新想法:

扩展对话框的参数以获取上下文,以便可以像这样调用它:

 stepDialog = EditStepFragmentDialog.newInstance(getActivity(), newRecipe); 

接下来使用添加的上下文而不是getActivity()在你的Dialog中:

 AlertDialog.Builder adb = new AlertDialog.Builder(context); 

我怀疑(不知道这个)SherlockFragment算作一个活动的实例,所以当你在对话框中调用getActivity()时,它被绑定到你的片段。