Xamarin Android:使用Alert Dialog保持控制,直到单击一个按钮

时间:2013-05-17 19:45:33

标签: android xamarin.android nsrunloop

我们正在使用静态警报对话框来获取用户对某些操作的确认。在我们对Show()的电话中,我们希望保持控制权,直到用户点击按钮,以便我们可以在Show()电话结束时返回按钮点击结果。

我们的iOS版本(UIAlertView)使用

while (displayed)
{
    MonoTouch.Foundation.NSRunLoop.Current.RunUntil(
            MonoTouch.Foundation.NSDate.FromTimeIntervalSinceNow(0.2));
}

Show()方法中,在返回按钮选择之前等待用户输入。

我们可以在Monodroid中使用与此等效的Android吗?

3 个答案:

答案 0 :(得分:4)

通过不同的设计解决:

我们不是等待用户与对话框进行交互,而是阻止其他所有内容,而是在我们调用静态EventHandler方法时提供Show,当用户点击按钮时会触发该方法:

public static void Show(string title, 
                        string message, 
                        Context context,
                        EventHandler handler,
                        ConfirmationAlertButton button) { ... }

我们维护对传入的EventHandler的私人引用,这些引用会在按钮点击时触发,如下所示:

private static void OkClicked(object sender, DialogClickEventArgs e)
{
    if (_handler != null)
    {
        _handler.Invoke(sender, e);
    }

    _instance.Dismiss();
    _instance = null;
    _handler = null;
}

以下是来自“活动”的Show调用的示例:

ConfirmationDialog.Show(@"Message title",
                        @"Message text",
                        this,
                        delegate
                        {
                            if (e.Result)
                            {
                                Finish();
                            }
                            else
                            {
                                Invalidate();
                            }
                        },
                        ConfirmationAlertButton.OK);

如果有人想了解有关在Xamarin Android应用程序中使用静态对话框的更多信息,请告诉我们!

答案 1 :(得分:2)

我通过创建一个为我显示对话框的AlertDialogHelper类来解决这个问题。只是想和你们分享我的解决方案。

助手类

public class AlertDialogHelper : Java.Lang.Object, IDialogInterfaceOnDismissListener
{
    Context context;
    ManualResetEvent waitHandle;
    string title;
    string message;
    string positiveButtonCaption;
    string negativeButtonCaption;
    bool dialogResult;

    public static async Task<bool> ShowAsync(Context context, string title, string message)
    {
        return await AlertDialogHelper.ShowAsync(context, title, message, "OK", "Cancel");
    }

    public static async Task<bool> ShowAsync(Context context, string title, string message, string positiveButton, string negativeButton)
    {
        return await new AlertDialogHelper(context, title, message, positiveButton, negativeButton).ShowAsync();
    }

    private AlertDialogHelper(Context context, string title, string message, string positiveButton, string negativeButton)
    {
        this.context = context;
        this.title = title;
        this.message = message;
        this.positiveButtonCaption = positiveButton;
        this.negativeButtonCaption = negativeButton;
    }

    private async Task<bool> ShowAsync()
    {
        this.waitHandle = new ManualResetEvent(false);
        new AlertDialog.Builder(this.context)
            .SetTitle(this.title)
            .SetMessage(this.message)
            .SetPositiveButton(this.positiveButtonCaption, OnPositiveClick)
            .SetNegativeButton(this.negativeButtonCaption, OnNegativeClick)
            .SetOnDismissListener(this)
            .Show();

        Task<bool> dialogTask = new Task<bool>(() =>
        {
            this.waitHandle.WaitOne();
            return this.dialogResult;
        });
        dialogTask.Start();
        return await dialogTask;
    }

    private void OnPositiveClick(object sender, DialogClickEventArgs e)
    {
        this.dialogResult = true;
        this.waitHandle.Set();
    }

    private void OnNegativeClick(object sender, DialogClickEventArgs e)
    {
        this.dialogResult = false;
        this.waitHandle.Set();
    }

    public void OnDismiss(IDialogInterface dialog)
    {
        this.dialogResult = false;
        this.waitHandle.Set();
    }
}

用法

// Default buttons
bool dialogResult = await AlertDialogHelper.ShowAsync(this, "Dialog title", "Some informative message.");

// Custom buttons
bool dialogResult = await AlertDialogHelper.ShowAsync(this, "Dialog title", "Some informative message.", "Yes", "No");

答案 2 :(得分:1)

你必须做两件事。首先覆盖后退按钮以防止用户退出活动。其次,您必须创建一个自定义对话框,在用户执行正确操作之前不断重新打开。这是因为用户可以在对话框外触摸以取消它,而无需使用对话框底部的按钮。

Here is a link to a previous post on creating the custom dialog

示例是在java中。如果您需要帮助转换为C#,我可以举个例子。

以下是覆盖后退按钮的方法。

public override bool OnKeyDown(Keycode keyCode, KeyEvent e)
    {
        if (keyCode == Keycode.Back && awaitConfirmation)
            return true;
        else
            return base.OnKeyDown(keyCode, e);
    }

awaitConfirmation变量将是一个局部变量(默认为false),在显示对话框之前设置为true,并在用户接受确认时设置为false。