我遇到了一些障碍.我的场景非常类似于
DialogFragment – retaining listener after screen rotation所描述的场景
建议的解决方案适用于作者,因为他的对话框是从活动中调用的.我的情况完全相同,但我的自定义对话框是从片段而不是活动调用的. (IE Activity-> Fragment-> Dialog)
我实现了相同的解决方案(从调用Fragment设置onResume中的监听器)但在这种情况下它不起作用.
似乎正在发生的事情是,当屏幕旋转时,Android会杀死对话框和片段.然后按顺序重新创建它们.因此,当在我的自定义对话框中调用onCreateDialog时,包含片段尚未重新创建,因此它为侦听器设置为正和负按钮时为null.
有没有人知道这方面的方法?
如果有人认为有必要,我可以发布代码,但它与链接线程上的代码几乎相同.
更新代码:
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; } }
解决方法
我查看了所讨论链接的所有选项,但没有一个解决方案最终为我工作.在进一步使用go / setTargetFragment和FragmentManager.put / getFragment之后,我还尝试了许多其他选项.这些对我来说也不起作用.然后我再看看:
http://developer.android.com/training/basics/fragments/communicating.html
他们特别说“两片碎片不应该直接沟通”.我认为这是真正证明是真实的案例之一.
我最终实现了那里提供的建议回调机制,并最终得到了这个:
在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) { ... }
这很好用,如果打开然后方向更改和编辑完成,它实际上会触发我需要在调用Fragment中运行的最终函数,而不是崩溃或不执行任何操作(null侦听器).