是/否对话框及其生命周期

4

我相信这是一个基本的问题,但我的研究没有发现有用的信息。我的新应用程序需要在某些情况下使用Yes/No对话框,但我不知道对话框如何适应应用程序的生命周期。例如,我想创建一个支持此类型结构的方法:

if (yesNoAlert("Title", "Do you want to try again?") == true) {
   action1();
} else {
   action2();
}

这个方法大致如下所示:
private boolean yesNoAlert(String title, String message) {
    final boolean returnValue;

    DialogInterface.OnClickListener dialogClickListener = new
                       DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            switch (which){
            case DialogInterface.BUTTON_POSITIVE:
                returnValue = true;
                break;

            case DialogInterface.BUTTON_NEGATIVE:
                returnValue=false;
                break;
            }
        }
    };

    alertbox = new AlertDialog.Builder(this);
    alertbox.setMessage(message)
            .setTitle(title)
            .setPositiveButton("Yes", dialogClickListener)
            .setNegativeButton("No", dialogClickListener)
            .show();
}

...但是正如您所看到的,它还没有完成——有很多事情不太正确。我缺少的部分是如何知道对话框已经完成......有什么方法可以被利用,使应用程序能够意识到按钮已被按下?当然,BUTTON_POSITIVE和BUTTON_NEGATIVE操作会响应此操作,但我的问题是如何返回一个指示器,以便等待响应的代码将在action1()或action2()处重新开始,取决于响应。

目前,我看不出任何方法让我的应用程序确定这一点,甚至从那段代码中创建一个有效的方法/函数的方法都不存在。因此,我在生命周期中缺少了一些关键的部分。

我应该在哪里阅读这个?当然,在互联网上有大量关于此的信息,但对于我这样的相对新手来说,就像试图从消防栓中喝水。


将returnValue变量从“局部方法变量”改为“类变量”。然后你就可以在onClick方法内部设置'returnValue'。 - Eric Leschinski
3个回答

2
这将使需要执行的操作具有动态性:
private Thread actionToDo;

private void yesNoAlert(String title, String message)
{
    DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
    {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                switch (which)
                {
                    case DialogInterface.BUTTON_POSITIVE:
                    actionToDo.start();
                    break;

                    case DialogInterface.BUTTON_NEGATIVE:
                    break;
                }
            }
    };
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(message).setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", dialogClickListener).setTitle(title).show();
}

1
你可以这样做。
private boolean yesNoAlert(String title, String message) {
    new AlertDialog.Builder(this).setMessage(message)
        .setTitle(title)
        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
             public void onClick(DialogInterface dialog, int which) { action1(); }
        })
        .setNegativeButton("No", new DialogInterface.OnClickListener() {
             public void onClick(DialogInterface dialog, int which) { action2(); }
        })
        .show();
}

是的,我明白。但是在代码中有几个地方可能需要是/否问题...结果可能会导致所有程序逻辑都被是/否对话框淹没。例如,请考虑以下情况:while userIsEnergetic { doSomething(result); if (result == AN_ERROR) { if (yesNoAlert(TITLE, "发生错误。继续尝试?")) { } else { if (yesNoAlert(TITLE, "尝试其他方法?")) { youGetTheDrill(); } } - Dennis
@Dennis,问题在于你无法从 yesNoAlert 返回 true/false 值。在对话框上调用 show() 不会阻塞,直到用户单击是或否按钮。相反,适当的 DialogInterface.OnClickListener 将稍后在主 UI 线程上被调用。如果你想将逻辑与 AlertDialog 分离,则可以例如将 yes/no 的 DialogInterface.OnClickListener 作为实例变量。 - denis.solonenko
@Dennis,这种过程式的方法行不通。你必须将与用户交互的代码转换为基于事件的模型。 - denis.solonenko
谢谢你的建议。我的主要问题是,我很多年前学习编程时,采用了完全不同的范式,并且一直非常成功。我可以做到这一点,但有些重新培训是必要的。我感谢你的指导,并将继续寻找关于不同范式之间差异的信息。 - Dennis

0

你可以使用监听器来实现这个功能。就像在Android文档中所说:

  1. 定义一个接口,包含你需要支持的操作(onDialogPositiveClickonDialogNegativeClick)。

    public class NoticeDialogFragment extends DialogFragment {

    /* 创建此对话框片段实例的活动必须实现此接口以接收事件回调。
     * 每个方法都传递了 DialogFragment,以便主机需要查询它。*/
    public interface NoticeDialogListener {
        public void onDialogPositiveClick(DialogFragment dialog);
        public void onDialogNegativeClick(DialogFragment dialog);
    }
    
    // 使用此接口的实例来传递操作事件
    NoticeDialogListener mListener;
    
    // 重写 Fragment.onAttach() 方法以实例化 NoticeDialogListener
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        // 验证主机活动是否实现了回调接口
        try {
            // 实例化 NoticeDialogListener,以便我们可以向主机发送事件
            mListener = (NoticeDialogListener) activity;
        } catch (ClassCastException e) {
            // 活动未实现接口,抛出异常
            throw new ClassCastException(activity.toString()
                    + " 必须实现 NoticeDialogListener");
        }
    }
    ...
    

    }

  2. 使显示对话框的类实现你的接口。

    public class MainActivity extends FragmentActivity implements NoticeDialogFragment.NoticeDialogListener{ ...

    public void showNoticeDialog() {
        // 创建对话框片段的实例并显示它
        DialogFragment dialog = new NoticeDialogFragment();
        dialog.show(getSupportFragmentManager(), "NoticeDialogFragment");
    }
    
    // 对话框片段通过 Fragment.onAttach() 回调接收到对此 Activity 的引用,
    // 它使用它来调用由 NoticeDialogFragment.NoticeDialogListener 接口定义的以下方法
    @Override
    public void onDialogPositiveClick(DialogFragment dialog) {
        // 用户触摸了对话框的正按钮
        ...
    }
    
    @Override
    public void onDialogNegativeClick(DialogFragment dialog) {
        // 用户触摸了对话框的负按钮
        ...
    }
    

    }

  3. 使你的对话框在正确的时刻调用这些方法(当检测到 setPositiveButtonsetNegativeButton 点击时)。

    public class NoticeDialogFragment extends DialogFragment { ...

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // 构建对话框并设置按钮单击处理程序
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.dialog_fire_missiles)
               .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // 将正按钮事件发送回主机活动
                       mListener.onDialogPositiveClick(NoticeDialogFragment.this);
                   }
               })
               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // 将负按钮事件发送回主机活动
                       mListener.onDialogNegativeClick(NoticeDialogFragment.this);
                   }
               });
        return builder.create();
    }
    

    }

参考 http://developer.android.com/guide/topics/ui/dialogs.html#PassingEvents


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接