将值从Dialog传递回Android上的Activity的强大方法?

时间:2012-11-17 21:49:49

标签: android dialog alertdialog

这个问题已经出现了几次,我已经阅读了所有答案,但我还没有看到一种真正有效的方法来处理这个问题。在我的解决方案中,我正在使用从调用ActivityAlertDialog的侦听器,如下所示:

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传递任何参数并设置我的监听器。

问题在于:当对话框打开时旋转设备并更改方向时,会重新创建ActivityMyDialogFragment个对象。为确保输入值不会搞砸,我将初始值设置为static。这对我来说很惹人讨厌,但由于一次只有一个这样的对话,我对此感到满意。出现问题的地方是返回值。原始的监听器将被调用。这很好,因为对象仍然存在,但是如果需要更新Activity上的UI(有),则不会更新,因为 new {{1实例现在正在控制UI。

我正在考虑的一个解决方案是在对话框类中将Activity转换为getActivity()并强制对话框本身添加一个监听器,而不是让调用Activity执行它。但这只是一种乱七八糟的黑客行为。

优雅地处理此问题的最佳做法是什么?

3 个答案:

答案 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。

Broadcasting and Receiving Intents

上查看本教程

答案 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();

}