Android 确认对话框返回 true 或 false

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10763986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:52:07  来源:igfitidea点击:

Android Confirmation dialog returning true or false

androiddialogconfirmation

提问by ilomambo

It seems to be there is no easy way to get an Alert dialog to return a simple value.
This code does not work(the answervariable cannot be set from within the listener, in fact it does not even compile)

似乎没有简单的方法可以让 Alert 对话框返回一个简单的值。
此代码不起作用(无法从侦听器中设置answer变量,实际上它甚至无法编译)

public static boolean Confirm(Context context) {
    boolean answer;
    AlertDialog dialog = new AlertDialog.Builder(context).create();
    dialog.setTitle("Confirmation");
    dialog.setMessage("Choose Yes or No");
    dialog.setCancelable(false);
    dialog.setButton(DialogInterface.BUTTON_POSITIVE, "Yes", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int buttonId) {
            answer = true;
        }
    });
    dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "No", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int buttonId) {
            answer = false;
        }
    });
    dialog.setIcon(android.R.drawable.ic_dialog_alert);
    dialog.show();
    return answer;
}

NOTE: It is important that the method is self contained, i.e., it does not depend on variables or constructs external to it. Just call it and get your answer, true or false.

注意:重要的是该方法是自包含的,即它不依赖于它外部的变量或构造。只需致电并获得您的答案,无论是对还是错。

So, what to do? This simple wish of returning trueor falseseems to be much more complicated than it deserves.

那么该怎么办?这个简单的返回truefalse 的愿望似乎比它应得的要复杂得多。

Also, the setButton method has the form:

此外,setButton 方法具有以下形式:

dialog.setButton(int buttonId, String buttonText, Message msg)

But it is not clear how to use it, where is the meesage sent to, to whom, which handler is used?

但不清楚如何使用它,消息发送到哪里,发送给谁,使用哪个处理程序?

采纳答案by ilomambo

Well, I was going to say that I am very pleased with myself because I found a simple answer, all by myself!
But the truth is that although I find a way to return a value (which I show below). It is of no use.

好吧,我想说我对自己很满意,因为我自己找到了一个简单的答案!
但事实是,尽管我找到了一种返回值的方法(如下所示)。这是没有用的

The real problem is I wanted a synchronous Dialog, a dialog that waits for the user to answer before resuming your code after dialog.show().
There is no such beast in Android. All dialogs are asynchronous, so dialog.show()only posts the dialog in some queue (I think) and continues. Thus you don't get your answer in time.

真正的问题是我想要一个同步对话框,一个等待用户回答的对话框,然后在dialog.show().
Android 中没有这样的野兽。所有对话框都是异步的,所以dialog.show()只在某个队列中发布对话框(我认为)并继续。因此,您没有及时得到答案。

For all its worth (nothing) below you'll find how to set a value inside the method that builds the dialog. Maybe there are other uses for this technique, not related to the dialog lifecycle.

对于它的所有价值(没有),您将在下面找到如何在构建对话框的方法中设置一个值。也许这种技术还有其他用途,与对话生命周期无关。







To give some related info, I'll say that if you replace

为了提供一些相关信息,我会说如果你更换

boolean answer;

with

final boolean answer;

it is possible to access the variable from within the listener, but it is not possible to assign it a new value, since it was declared as final.

可以从侦听器内部访问该变量,但不能为其分配新值,因为它被声明为final

Here comes the trick.
Define the variable as:

诀窍来了。
将变量定义为:

final boolean[] answer = new boolean[1];

Some of you already see why this will work. The final variable here is not the single element of the boolean array, is the array itself.
So now you can assign the array element [0] as you wish.

你们中的一些人已经明白为什么这会奏效。这里的最终变量不是布尔数组的单个元素,而是数组本身。
所以现在您可以根据需要分配数组元素 [0]。

dialog.setButton(DialogInterface.BUTTON_POSITIVE, "Yes", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int buttonId) {
        answer[0] = true;
    }
});
. . .
return answer[0];

And finally you can return it from your method.

最后你可以从你的方法中返回它。

回答by AsepRoro

i have post similiar problem in this forum, but finally i get my answer. my problem in that post is how to create separate confirm dialog class who can acces by other class or activity, so with that confirm dialog class we don't need to write long coding.

我在这个论坛上发布了类似的问题,但最后我得到了答案。我在那篇文章中的问题是如何创建可以被其他类或活动访问的单独的确认对话框类,因此使用该确认对话框类,我们不需要编写长代码。

here's my answer.

这是我的答案。

First you must create DialogHandler.java

首先你必须创建DialogHandler.java

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import src.app.R;

public class DialogHandler {
    public Runnable ans_true = null;
    public Runnable ans_false = null;

    // Dialog. --------------------------------------------------------------

    public boolean Confirm(Activity act, String Title, String ConfirmText,
            String CancelBtn, String OkBtn, Runnable aProcedure, Runnable bProcedure) {
        ans_true = aProcedure;
        ans_false= bProcedure;
        AlertDialog dialog = new AlertDialog.Builder(act).create();
        dialog.setTitle(Title);
        dialog.setMessage(ConfirmText);
        dialog.setCancelable(false);
        dialog.setButton(DialogInterface.BUTTON_POSITIVE, OkBtn,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int buttonId) {
                         ans_true.run();
                    }
                });
        dialog.setButton(DialogInterface.BUTTON_NEGATIVE, CancelBtn,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int buttonId) {
                        ans_false.run();
                    }
                });
        dialog.setIcon(android.R.drawable.ic_dialog_alert);
        dialog.show();
        return true;
    }
}

And this is example to call it in another class

这是在另一个类中调用它的示例

public class YourActivity extends Activity {
    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.button1).setOnClickListener(myclick);
    }

    public final Button.OnClickListener myclick = new Button.OnClickListener() {
        @Override
        public void onClick(View v) {
            doclick();
        }
    };

    public void doclick() {
        DialogHandler appdialog = new DialogHandler();
        appdialog.Confirm(this, "Message title", "Message content",
                "Cancel", "OK", aproc(), bproc());
    }

    public Runnable aproc(){
        return new Runnable() {
            public void run() {
                Log.d("Test", "This from A proc");
            }
          };
    }

    public Runnable bproc(){
        return new Runnable() {
            public void run() {
                Log.d("Test", "This from B proc");
            }
          };
    }


}

回答by Lalit Poptani

What you can do is create a Listener for your Alert Dialog that listens to AlertDialogs action using an Interface.

您可以做的是为您的警报对话框创建一个侦听器,该侦听器使用接口侦听 AlertDialogs 操作。

Create an Interface.

创建一个接口。

public class MyInterface {

    DialogReturn dialogReturn;

    public interface DialogReturn {

        void onDialogCompleted(boolean answer);
    }

    public void setListener(DialogReturn dialogReturn) {
        this.dialogReturn = dialogReturn;
    }

    public DialogReturn getListener() {
        return dialogReturn;

    }
}

Now, in your class just implement the Interface that you created using implements MyInterface.DialogReturn

现在,在您的类中只需实现您使用创建的接口 implements MyInterface.DialogReturn

then you can set the Listener and get it working as show below,

然后你可以设置监听器并让它如下所示工作,

public class Main extends Activity implements MyInterface.DialogReturn{

    MyInterface myInterface;
    MyInterface.DialogReturn dialogReturn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
                ....
        myInterface = new MyInterface();
        myInterface.setListener(this);
    }


   public void Confirm(Context context) {
        AlertDialog dialog = new AlertDialog.Builder(context).create();
        dialog.setTitle("Confirmation");
        dialog.setMessage("Choose Yes or No");
        dialog.setCancelable(false);
        dialog.setButton(DialogInterface.BUTTON_POSITIVE, "Yes", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int buttonId) {
                myInterface.getListener().onDialogCompleted(true);
            }
        });
        dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "No", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int buttonId) {
                myInterface.getListener().onDialogCompleted(false);
            }
        });
        dialog.setIcon(android.R.drawable.ic_dialog_alert);
        dialog.show();
         }


@Override
    public void onDialogCompleted(boolean answer) {
        Toast.makeText(Main.this, answer+"", Toast.LENGTH_LONG).show();
            if(answer)
            // do something
            else
            // do something
    }
}

回答by Peter Ajtai

I find that using jDeferredhelps in cases where you want to wait for input.

我发现在您想要等待输入的情况下,使用jDeferred 会有所帮助。

It is essentially equivalent to using an interface, but instead you create done and fail handlers. Just an alternative to consider:

它本质上等同于使用接口,但您创建的是 done 和 fail 处理程序。只是考虑的替代方案:

new ConfirmationDialog(mContext)
        .showConfirmation("Are you sure?", "Yes", "No")
        .done(new DoneCallback<Void>() {
            @Override
            public void onDone(Void aVoid) {
                ....
            }
        })
        .fail(new FailCallback<Void>() {

            @Override
            public void onFail(Void aVoid) {
                ...
            }
        });

Implementation:

执行:

public class ConfirmationDialog {


    private final Context mContext;
    private final DeferredObject<Void, Void, Void> mDeferred = new DeferredObject<Void, Void, Void>();

    public ConfirmationDialog(Context context) {
        mContext = context;
    }

    public Promise<Void, Void, Void> showConfirmation(String message, String positiveButton, String negativeButton) {
        AlertDialog dialog = new AlertDialog.Builder(mContext).create();
        dialog.setTitle("Alert");
        dialog.setMessage(message);
        dialog.setCancelable(false);
        dialog.setButton(DialogInterface.BUTTON_POSITIVE, positiveButton, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int buttonId) {
                mDeferred.resolve(null);
            }
        });
        dialog.setButton(DialogInterface.BUTTON_NEGATIVE, negativeButton, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int buttonId) {
                mDeferred.reject(null);
            }
        });
        dialog.setIcon(android.R.drawable.ic_dialog_alert);
        dialog.show();
        return mDeferred.promise();
    }

}

回答by robcalvo

With Andriod, it is not a good idea to block the running thread by waiting for the user to say 'yes' or 'no'.

对于 Andriod,通过等待用户说“是”或“否”来阻止正在运行的线程并不是一个好主意。

In order to ask for a confirmation, you can define a method that receives an AsynTask. The method executes that task if the user press the confirm button.

为了请求确认,您可以定义一个接收 AsynTask 的方法。如果用户按下确认按钮,该方法将执行该任务。

For example:

例如:

    //this method displays a confirm dialog. If 'yes' answer, runs 'yesTask', 
    //if 'no' answer, runs 'noTask'
    //notice than 'yesTask' and 'noTask' are AysncTask
    //'noTask' can be null, example: if you want to cancel when 'no answer'

    public static void confirm(Activity act, String title, String confirmText,
                       String noButtonText, String yesButtonText,
                       final AsyncTask<String, Void, Boolean> yesTask,
                       final AsyncTask<String, Void, Boolean> noTask) {

    AlertDialog dialog = new AlertDialog.Builder(act).create();
    dialog.setTitle(title);
    dialog.setMessage(confirmText);
    dialog.setCancelable(false);
    dialog.setButton(DialogInterface.BUTTON_POSITIVE, yesButtonText,
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int buttonId) {
                yesTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
            }
        });
    dialog.setButton(DialogInterface.BUTTON_NEGATIVE, noButtonText,
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int buttonId) {
                if(noTask!=null) {
                    noTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                }

            }
        });
    dialog.setIcon(android.R.drawable.ic_dialog_alert);
    dialog.show();
}

You can call it from your activity with:

您可以通过以下方式从您的活动中调用它:

 YourTask yourTask =  new YourTask( ... );
 confirm( YourActivity.this, 
         "Confirm", 
         "Are you sure?", 
         "Cancel", 
         "Continue", 
         yourTask,
         null);

YourTaskclass must extend AsyncTask

YourTask类必须扩展 AsyncTask

回答by mmarin1m

I've tried all of the solutions and the easier and cleanest is by far the first solution with the Runnable, in my opinion. It supports the dialog on the Cancel button listener, the OnBAckPressed() and the onOptionsItemSelected().

我已经尝试了所有的解决方案,在我看来,最简单和最干净的是 Runnable 的第一个解决方案。它支持取消按钮侦听器、OnBAckPressed() 和 onOptionsItemSelected() 上的对话框。

The code as described though calls the ans_false.run(); when clicking the BUTTON_POSITIVE and the ans_true.run(); when clicking the BUTTON_NEGATIVE.

所描述的代码虽然调用 ans_false.run(); 单击 BUTTON_POSITIVE 和 ans_true.run() 时;单击 BUTTON_NEGATIVE 时。

Here is the code I used to fix that problem:

这是我用来解决该问题的代码:

public class MyDialogs {

// private constructor
public Runnable answerTrue = null;
public Runnable answerFalse = null;

// Dialog. --------------------------------------------------------------

public boolean confirm(Activity act, String Title, String ConfirmText,
                       String noBtn, String yesBtn, Runnable yesProc, Runnable noProc) {
    answerTrue = yesProc;
    answerFalse= noProc;
    AlertDialog.Builder alert = new AlertDialog.Builder(act);
    alert.setTitle(Title);
    alert.setMessage(ConfirmText);
    alert.setCancelable(false);
    alert.setPositiveButton(R.string.button_positive, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            answerTrue.run();
        }
    });
    alert.setNegativeButton(R.string.button_negative, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            answerFalse.run();
        }
    });
    alert.show().getButton(DialogInterface.BUTTON_NEGATIVE).requestFocus();
    return true;
}

}

}

回答by Guillaume

I was also struggling to use a blocking confirm dialog and I finally did it using a BlockingQueue :

我也在努力使用阻塞确认对话框,我终于使用 BlockingQueue 做到了:

public static class BlockingConfirmDialog{

    private Activity context;

    BlockingQueue<Boolean> blockingQueue;

    public BlockingConfirmDialog(Activity activity) {
        super();
        this.context = activity;
        blockingQueue = new ArrayBlockingQueue<Boolean>(1);
    }

    public boolean confirm(final String title, final String message){

        context.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                new AlertDialog.Builder(context)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) { 
                        blockingQueue.add(true);
                    }
                 })
                 .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        blockingQueue.add(false);
                    }
                })
                 .show();
            }
        });

        try {
            return blockingQueue.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }

    }
}

回答by Vladimir Ivanov

Declare a field 'answer' in your activity and set a value to it. Fields of a class are visible to inner classes, so you can do that.

在您的活动中声明一个字段“答案”并为其设置一个值。类的字段对内部类可见,因此您可以这样做。