12

アラートダイアログで単純な値を返す簡単な方法はないようです。
このコードは機能しません(リスナー内から回答変数を設定することはできません。実際、コンパイルすらしません)

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

注:メソッドが自己完結型であることが重要です。つまり、メソッドの外部の変数や構成に依存しないことが重要です。ただそれを呼んで、あなたの答えを、真か偽かを問わず得てください。

じゃあ何をすればいいの?trueまたはfalseを返すというこの単純な願いは、それに値するよりもはるかに複雑なようです。

また、setButtonメソッドの形式は次のとおりです。

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

しかし、それをどのように使用するか、メッセージはどこに送信され、誰に、どのハンドラーが使用されるのかは明確ではありません。

4

8 に答える 8

10

さて、私は簡単な答えをすべて自分で見つけたので、私は自分自身に非常に満足していると言うつもりでした!
しかし、真実は、値を返す方法を見つけたとしても(以下に示します)、ということです。役に立たない

本当の問題は、同期ダイアログ、つまりユーザーが応答するのを待ってからコードを再開するダイアログが必要だったことdialog.show()です。
Androidにはそのような獣はありません。すべてのダイアログは非同期であるためdialog.show()、ダイアログを一部のキューに投稿するだけで(私は思う)、続行します。したがって、あなたは時間内にあなたの答えを得ることができません。

以下のすべての価値(何もない)については、ダイアログを構築するメソッド内で値を設定する方法を説明します。ダイアログのライフサイクルとは関係なく、この手法には他の用途があるかもしれません。




いくつかの関連情報を与えるために、私はあなたが置き換えるならばそれを言うでしょう

boolean answer;

final boolean answer;

リスナー内から変数にアクセスすることは可能ですが、 finalとして宣言されているため、新しい値を割り当てることはできません。

ここにトリックがあります。
変数を次のように定義します。

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

なぜこれが機能するのか、すでにご存知の方もいらっしゃいます。ここでの最後の変数はブール配列の単一要素ではなく、配列自体です。
これで、必要に応じて配列要素[0]を割り当てることができます。

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

そして最後に、メソッドからそれを返すことができます。

于 2012-05-26T14:34:36.330 に答える
5

できることは、Interface を使用して AlertDialogs アクションをリッスンするアラート ダイアログのリスナーを作成することです。

インターフェイスを作成します。

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;

    }
}

今、あなたのクラスであなたが作成したインターフェースを実装するだけですimplements MyInterface.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
    }
}
于 2012-05-26T06:38:54.513 に答える
1

Andriod では、ユーザーが「はい」または「いいえ」と言うのを待って実行中のスレッドをブロックするのは得策ではありません。

確認を求めるために、AsynTask を受け取るメソッドを定義できます。ユーザーが確認ボタンを押すと、メソッドはそのタスクを実行します。

例えば:

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

YourTaskクラスは拡張する必要がありますAsyncTask

于 2015-04-18T12:30:54.430 に答える
1

jDeferredを使用すると、入力を待ちたい場合に役立ちます。

基本的にはインターフェイスを使用するのと同じですが、代わりに 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) {
                ...
            }
        });

実装:

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

}
于 2013-09-26T23:13:55.560 に答える
0

ブロッキング確認ダイアログの使用にも苦労していましたが、最終的に 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;
        }

    }
}
于 2013-08-05T14:47:49.557 に答える
0

アクティビティで「answer」フィールドを宣言し、それに値を設定します。クラスのフィールドは内部クラスから見えるので、そうすることができます。

于 2012-05-26T06:03:36.440 に答える