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

Eri*_*nge 6 android dialog android-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();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在调用中Activity,我正常实例化对象,传入任何参数init并设置我的监听器.

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

我正在考虑的一个解决方案是getActivity()在对话框类中向我Activity强制转换并强制对话框本身添加一个监听器,而不是Activity让它进行调用.但这只是感觉像黑客的滚雪球.

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

ant*_*tew 21

您走在正确的轨道上,我遵循Android开发者推荐的方法- 使用DialogFragments文章.

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

public interface MyDialogFragmentListener {
    public void onReturnValue(String foo);
}
Run Code Online (Sandbox Code Playgroud)

然后在DialogFragment中,当您想要将结果返回给Activity时,您将活动转换为接口:

@Override
public void onClick(DialogInterface dialog, int id) {
    MyDialogFragmentListener activity = (MyDialogFragmentListener) getActivity();
    activity.onReturnValue("some value");
}
Run Code Online (Sandbox Code Playgroud)

然后在Activity你实现该接口并获取值:

public class MyActivity implements MyDialogFragmentListener {
    ...
    @Override
    public void onReturnValue(String foo) {
        Log.i("onReturnValue", "Got value " + foo + " back from Dialog!");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我可能会使用该接口让控制流返回到Activity并让它启动第二个DialogFragment.听起来像一个有趣的问题,用例是什么? (2认同)