这个问题已经出现了几次,我已经阅读了所有答案,但我还没有看到一种真正有效的方法来处理这个问题。在我的解决方案中,我正在使用从调用Activity
到AlertDialog
的侦听器,如下所示:
public class MyDialogFragment extends DialogFragment {
public interface MyDialogFragmentListener {
public void onReturnValue(String foo);
}
public void init(boolean someValue)
{
sSomeValue = someValue;
listeners = new ArrayList<MyDialogFragmentListener>();
}
static boolean sSomeValue;
private static ArrayList<MyDialogFragmentListener> listeners;
public void addMyDialogFragmentListener(MyDialogFragmentListener l)
{
listeners.add(l);
}
public void removeMyDialogFragmentListener(MyDialogFragmentListener l)
{
listeners.remove(l);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.title)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
for (MyDialogFragmentListener listener : listeners) {
listener.onReturnValue("some value");
}
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
// Nothing to do but exit
}
});
if (sSomeValue) {
builder.setMessage(R.string.some_value_message);
} else {
builder.setMessage(R.string.not_some_value_message);
}
// Create the AlertDialog object and return it
return builder.create();
}
}
然后在调用Activity
中,我正常实例化对象,通过init
传递任何参数并设置我的监听器。
问题在于:当对话框打开时旋转设备并更改方向时,会重新创建Activity
和MyDialogFragment
个对象。为确保输入值不会搞砸,我将初始值设置为static
。这对我来说很惹人讨厌,但由于一次只有一个这样的对话,我对此感到满意。出现问题的地方是返回值。原始的监听器将被调用。这很好,因为对象仍然存在,但是如果需要更新Activity
上的UI(有),则不会更新,因为 new {{1实例现在正在控制UI。
我正在考虑的一个解决方案是在对话框类中将Activity
转换为getActivity()
并强制对话框本身添加一个监听器,而不是让调用Activity
执行它。但这只是一种乱七八糟的黑客行为。
优雅地处理此问题的最佳做法是什么?
答案 0 :(得分:21)
您走在正确的轨道上,我遵循Android Developers - Using DialogFragments article推荐的方法。
您创建了DialogFragment并定义了Activity将实现的接口,就像您上面所做的那样:
public interface MyDialogFragmentListener {
public void onReturnValue(String foo);
}
然后在DialogFragment中,当您想要将结果返回给Activity时,您将活动转换为界面:
@Override
public void onClick(DialogInterface dialog, int id) {
MyDialogFragmentListener activity = (MyDialogFragmentListener) getActivity();
activity.onReturnValue("some value");
}
然后在Activity
中实现该接口并获取值:
public class MyActivity implements MyDialogFragmentListener {
...
@Override
public void onReturnValue(String foo) {
Log.i("onReturnValue", "Got value " + foo + " back from Dialog!");
}
}
答案 1 :(得分:2)
您可以从Activity将要侦听的Dialog onClickListener中激活一个Intent。
上查看本教程答案 2 :(得分:0)
很老的帖子但是......
我在对话框类中有适当的变量:
int selectedFooStatus = 0;
在对话框与以下内容交互时操作它们:
.setSingleChoiceItems(FOO_CHOICES, -1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
selectedFooStatus = which;
}})
在onclick回调方法中,我适当地转换了返回的片段,并使用getter返回值。
public void onDialogPositiveClick(DialogFragment dialog) {
ChangeFooStatusDialog returnedDialog = (ChangeFooStatusDialog) dialog;
this.fooStatus = returnedDialog.getSelectedFooStatus();
}