English 中文(简体)
Android 确认对话框返回真实或错误
原标题:Android Confirmation dialog returning true or false

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 answer variable cannot be set from within the listener, in fact it does not even compile)

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;
}

注意: 方法必须是自我约束的, 也就是说, 它并不取决于变量或外部构造 。 只要称呼它, 并获得您的答案, 不管是真实的还是虚假的 。

那么,要做什么?这个简单的愿望是返回“false < true ”或“farse 似乎比它应得的要复杂得多。

此外,设定按钮方法的形式如下:

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

但是,不清楚如何使用它,哪里是迷因被送到哪去,谁被使用,谁被使用?

最佳回答

Well, I was going to say that I am very pleased 与 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.

在您下面的所有价值( 什么都没有) 中, 将会找到如何在构建对话框的方法中设定值 。 也许该技术还有其他用途, 与对话框的生命周期无关 。


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

boolean answer;

final boolean answer;

it is possible to access the variable from 与in the listener, but it is not possible to assign it a new value, since it was declared as 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.

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

最后你可以用你的方法把它还回来

问题回答

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.

这是我的答案。

首先您必须创建 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;
    }
}

这是在另一类中叫它的例子

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");
            }
          };
    }


}

您可以为您的警告对话框创建一个聆听器, 使用接口监听 AwardDialogs 动作 。

创建接口 。

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;

    }
}

现在, 在您的班级中, 只需执行您使用 < code> 执行我的Interface. DialogReturn 创建的界面 。

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

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
    }
}

我发现使用"https://github.com/jdeferred/jdeferred"rel=“nofollow”>jDeferred 帮助您在等待输入的情况下。

它基本上相当于使用接口,但你却创建了完成和失败的处理器。

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) {
                ...
            }
        });

执行:

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();
    }

}

透过等待用户同意或拒绝, 封锁运行线并非明智之计。

要请求确认, 您可以定义一个接收 AsynTashsk 的方法。 如果用户按下确认按钮, 该方法会执行此项任务 。

例如:

    //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();
}

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

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

您的 Task 类必须扩展 Asynctask

在您的活动中声明字段回答并设定其值。 某类的字段在内部类中可见, 这样您就可以做到这一点 。

也试图使用屏蔽确认对话,

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;
        }

    }
}

我尝试过所有解决方案, 在我看来, 最简单、最清洁的解决方案是第一个使用可运行选项的解决方案。 它支持取消按键监听器、 OnbackPresed () 和 Outblicts Epeoplemed () 的对话 。

所描述的代码调用 ass_false. run (); 当点击 Button_ positive 和 ans_ true. run () 时, 当点击 Button_ negative 时, 所描述的代码调用 ass_ false. run (); 当点击 Button_ positive 和 ans_ true. run () 时, 当点击 Button_ negative 时 。

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

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;
时 时

时 时





相关问题
Android - ListView fling gesture triggers context menu

I m relatively new to Android development. I m developing an app with a ListView. I ve followed the info in #1338475 and have my app recognizing the fling gesture, but after the gesture is complete, ...

AsyncTask and error handling on Android

I m converting my code from using Handler to AsyncTask. The latter is great at what it does - asynchronous updates and handling of results in the main UI thread. What s unclear to me is how to handle ...

Android intent filter for a particular file extension?

I want to be able to download a file with a particular extension from the net, and have it passed to my application to deal with it, but I haven t been able to figure out the intent filter. The ...

Android & Web: What is the equivalent style for the web?

I am quite impressed by the workflow I follow when developing Android applications: Define a layout in an xml file and then write all the code in a code-behind style. Is there an equivalent style for ...

TiledLayer equivalent in Android [duplicate]

To draw landscapes, backgrounds with patterns etc, we used TiledLayer in J2ME. Is there an android counterpart for that. Does android provide an option to set such tiled patterns in the layout XML?

Using Repo with Msysgit

When following the Android Open Source Project instructions on installing repo for use with Git, after running the repo init command, I run into this error: /c/Users/Andrew Rabon/bin/repo: line ...

Android "single top" launch mode and onNewIntent method

I read in the Android documentation that by setting my Activity s launchMode property to singleTop OR by adding the FLAG_ACTIVITY_SINGLE_TOP flag to my Intent, that calling startActivity(intent) would ...

From Web Development to Android Development

I have pretty good skills in PHP , Mysql and Javascript for a junior developer. If I wanted to try my hand as Android Development do you think I might find it tough ? Also what new languages would I ...

热门标签