8

这个问题已经出现了好几次,我已经阅读了所有的答案,但我还没有看到一个真正强大的方法来处理这个问题。在我的解决方案中,我正在使用来自调用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,它不会被更新,因为 Activity实例现在正在控制 UI。

我正在考虑的一种解决方案是getActivity()将对话框类强制转换为 myActivity并强制对话框本身添加一个侦听器,而不是让调用Activity来执行它。但这只是感觉就像黑客滚雪球一样。

优雅地处理这个问题的最佳实践是什么?

4

3 回答 3

24

你在正确的轨道上,我按照Android 开发者推荐的方法 - 使用 DialogFragments 文章

您创建 DialogFragment 并定义 Activity 将实现的接口,就像您在上面所做的那样:

public interface MyDialogFragmentListener {
    public void onReturnValue(String foo);
}

然后在 DialogFragment 中,当您想将结果返回给 Activity 时,您将 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!");
    }
}
于 2012-11-17T22:00:49.853 回答
2

您可以从 Dialog 的 onClickListner 中触发 Activity 将监听的 Intent。

看看这个关于广播和接收意图的教程

于 2012-11-17T22:00:06.933 回答
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();

}
于 2014-06-24T19:45:33.580 回答