Android"最佳实践"从对话框返回值

Pet*_*son 54 android

从复杂的自定义对话框(例如,文本字段,日期或时间选择器,一堆单选按钮等)以及"保存"和"取消"按钮将值返回到调用活动的"正确"方法是什么?

我在网上看到的一些技术包括:

  • Dialog派生类中的公共数据成员,可以由Activity读取

  • 公共"获取"访问者..."......" ."

  • 有意向启动的对话框(而不是显示() ),加上在对话框类处理它采取从各种控制输入和捆绑起来传递回活动,所以当听众打"保存"捆绑传回使用 ReturnIntent()

  • Activity中的监听器处理对话框中控件的输入,例如,TimePicker或DatePicker的监听器实际上在Activity中.在这个方案中,几乎所有的工作都在活动中完成

  • "活动"中的一个监听器为"保存"按钮,然后活动直接询问对话框中的控件; 活动解除了对话框.

......加上我已经忘记的更多.

是否有一种被认为是规范正确或"最佳实践"方法的特定技术?

Com*_*ish 20

也许我误解了你的问题,但为什么不使用内置的监听系统:

builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int id) {
        // run whatever code you want to run here
        // if you need to pass data back, just call a function in your
        // activity and pass it some parameters
    }
})
Run Code Online (Sandbox Code Playgroud)

这就是我总是处理对话框中的数据的方式.

编辑:让我给你一个更具体的例子,它将更好地回答你的问题.我要从这个页面窃取一些示例代码,您应该阅读:

http://developer.android.com/guide/topics/ui/dialogs.html

// Alert Dialog code (mostly copied from the Android docs
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a color");
builder.setItems(items, new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int item) {
        myFunction(item);
    }
});
AlertDialog alert = builder.create();
Run Code Online (Sandbox Code Playgroud)

...

// Now elsewhere in your Activity class, you would have this function
private void myFunction(int result){
    // Now the data has been "returned" (as pointed out, that's not
    // the right terminology)
}
Run Code Online (Sandbox Code Playgroud)

  • 我的问题是,是否有一种返回值的最佳实践方法.您所描述的是活动如何知道用户已完成.一旦用户完成,有很多方法可以返回值,但我不知道其中一个是否是最佳实践. (4认同)
  • 问题在于术语.你没有从对话框"返回".它不是方法或功能.它没有返回值.你想在用户点击对话框中的内容时运行一些代码.该代码也可能关闭对话框,但这并不意味着它返回一个值.就像计算机发布一样,这样做的方法是为对话框中的"完成"和"取消"按钮分配一个onclick处理程序.除此之外,他们调用<your activity> .dismissDialog(...),当然可以在您的活动中调用方法. (4认同)

小智 7

对于我的MIDI应用程序,我需要是/否/取消确认对话框,所以我首先制作了一般的StandardDialog类:

public class StandardDialog {

    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.DialogInterface;
    import android.os.Handler;

    public class StandardDialog {
    public static final int dlgResultOk         = 0;
    public static final int dlgResultYes        = 1;
    public static final int dlgResultNo         = 2;
    public static final int dlgResultCancel     = 3;

    public static final int dlgTypeOk           = 10;
    public static final int dlgTypeYesNo        = 11;
    public static final int dlgTypeYesNoCancel  = 12;

    private Handler mResponseHandler;
    private AlertDialog.Builder mDialogBuilder;
    private int mDialogId;

    public StandardDialog(Activity parent, 
                          Handler reponseHandler, 
                          String title, 
                          String message, 
                          int dialogType, 
                          int dialogId) {

        mResponseHandler = reponseHandler;
        mDialogId = dialogId;
        mDialogBuilder = new AlertDialog.Builder(parent);
        mDialogBuilder.setCancelable(false);
        mDialogBuilder.setTitle(title);
        mDialogBuilder.setIcon(android.R.drawable.ic_dialog_alert);
        mDialogBuilder.setMessage(message);
        switch (dialogType) {
        case dlgTypeOk:
            mDialogBuilder.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    mResponseHandler.sendEmptyMessage(mDialogId + dlgResultOk);
                }
            });         
            break;

        case dlgTypeYesNo:
        case dlgTypeYesNoCancel:
            mDialogBuilder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    mResponseHandler.sendEmptyMessage(mDialogId + dlgResultYes);
                }
            });         
            mDialogBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    mResponseHandler.sendEmptyMessage(mDialogId + dlgResultNo);
                }
            });         
            if (dialogType == dlgTypeYesNoCancel) {
                mDialogBuilder.setNeutralButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        mResponseHandler.sendEmptyMessage(mDialogId + dlgResultCancel);
                    }
                });         
            }
            break;
        }
        mDialogBuilder.show();
    }
}
Run Code Online (Sandbox Code Playgroud)

接下来,在我的主要活动中,我已经有来自其他线程的UI更新的消息处理程序,所以我只是添加了用于处理来自对话框的消息的代码.通过在我为各种程序函数实例化StandardDialog时使用不同的dialogId参数,我可以执行正确的代码来处理对不同问题的是/否/取消响应.这个想法可以通过发送数据包扩展到复杂的自定义对话框,虽然这比简单的整数消息要慢得多.

private Handler uiMsgHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {
        if (msg != null) {

            // {Code to check for other UI messages here}

            // Check for dialog box responses
            if (msg.what == (clearDlgId + StandardDialog.dlgResultYes)) {
                doClearDlgYesClicked();
            }
            else if (msg.what == (recordDlgId + StandardDialog.dlgResultYes)) {
                doRecordDlgYesClicked();
            }
            else if (msg.what == (recordDlgId + StandardDialog.dlgResultNo)) {
                doRecordDlgNoClicked();
            }
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

然后我需要做的就是在活动中定义do {Whatever}()方法.为了调出一个对话框,作为一个例子,我有一个方法响应"清除记录的MIDI事件"按钮并确认如下:

public void onClearBtnClicked(View view) {
    new StandardDialog(this, uiMsgHandler, 
        getResources().getString(R.string.dlgTitleClear),
        getResources().getString(R.string.dlgMsgClear), 
        StandardDialog.dlgTypeYesNo, clearDlgId);
}
Run Code Online (Sandbox Code Playgroud)

clearDlgId在其他地方被定义为唯一的整数.此方法在活动前面弹出"是/否"对话框,在对话框关闭之前会丢失焦点,此时活动会收到带有对话框结果的消息.然后,doClearDlgYesClicked()如果单击"是"按钮,则消息处理程序将调用该方法.(我不需要"否"按钮的消息,因为在那种情况下不需要采取任何行动).

无论如何,这种方法对我有用,并且可以很容易地从对话框中传回结果.


Bar*_*ica 5

我正在使用以下方式:

  1. 我的所有活动都有一个相同的父活动(比如说 ControlActivity)。ControlActivity 具有private volatile Bundle controlBundle;适当的 getter/setter
  2. 当我开始对话时,我曾经通过我自己的方法调用对话:

    public void showMyDialog(int id, Bundle bundle)
    {
        this.controlBundle=bundle;
        this.showDialog(id, bundle);
    }
    
    Run Code Online (Sandbox Code Playgroud)

所以每次我知道参数发送到对话框

  1. 当对话即将完成时,我在对话中形成另一个Bundle具有必要值的对话,然后将它们通过我的Activity捆绑设置器:

((ControlActivity )this.getOwnerActivity).setControlBundle(bundle);
Run Code Online (Sandbox Code Playgroud)

所以最后当对话框结束时,我知道从对话框“返回”的值。我知道这并不int retCode=this.showMyDialog();复杂,但它是可行的。