Xamarin Forms的Toast等效功能

116

是否有使用Xamarin Forms(而不是Android或iOS特定)创建弹出窗口的方法,就像Android使用Toast一样,不需要用户交互,并且在(短暂的)一段时间后消失?

从搜索中发现,所有我看到的都需要用户点击才能消失的警报。

21个回答

3
这是我改进后的 ShowAlert 版本,以确保即使在弹出页面上也会显示提示。 此外,如果用户点击提示框之外的区域,则提示框将被解除。 我使用了类似于提示框的 UIAlertControllerStyle.ActionSheet,它也适用于 UIAlertControllerStyle.Alert
    void ShowAlert(string message, double seconds)
    {
        var alert = UIAlertController.Create(null, message, UIAlertControllerStyle.ActionSheet);

        var alertDelay = NSTimer.CreateScheduledTimer(seconds, obj =>
        {
            DismissMessage(alert, obj);
        });

        var viewController = UIApplication.SharedApplication.KeyWindow.RootViewController;
        while (viewController.PresentedViewController != null)
        {
            viewController = viewController.PresentedViewController;
        }
        viewController.PresentViewController(alert, true, () =>
        {
            UITapGestureRecognizer tapGesture = new UITapGestureRecognizer(_ => DismissMessage(alert, null));
            alert.View.Superview?.Subviews[0].AddGestureRecognizer(tapGesture);
        });
    }

我希望这能对某些人有所帮助!


太棒了,而且还能正常工作。特别是弹出页面的解决方案非常好。谢谢。 - Emil

1

在Forms中没有内置机制,但这个NuGet包提供了类似的功能。

https://github.com/EgorBo/Toasts.Forms.Plugin

注意:这些不是问题中要求的Android风格的toast,而是UWP风格的toast,它们是系统范围的通知。

5
Android Toast 的意思是完全不同的东西——它是一种弹出式消息。这个库是用来实现系统范围通知的。 - Vojtěch Sázel
在安装库之前应该先阅读评论,才能注意到这些不是Android风格的toast。请在回答中明确说明这一点。 - findusl

1

1
我使用了Rg.Plugins.Popup NuGet来定制一个自定义弹出窗口 这是一个示例:
 <pages:PopupPage.Animation>
    <animations:ScaleAnimation 
        PositionIn="Center"
        PositionOut="Center"
        ScaleIn="1.2"
        ScaleOut="0.8"
        DurationIn="600"
        DurationOut="600"
        EasingIn="Linear"
       EasingOut="Linear"/>
</pages:PopupPage.Animation>

<Frame CornerRadius="10"  
    HeightRequest="30"
       VerticalOptions="End"
       HorizontalOptions="Fill"
       HasShadow="False"
        Padding="0" Margin="40,50"
       OutlineColor="LightGray">
    <StackLayout 
    Opacity="0.4"
       BackgroundColor="White">
    <Label
        x:Name="lbl"
        LineBreakMode="WordWrap"
        HorizontalTextAlignment="Center"
                    VerticalTextAlignment="Center"

        VerticalOptions="CenterAndExpand"
        HorizontalOptions="Center" TextColor="Black" FontSize="12">
                <Label.FontFamily>
                    <OnPlatform x:TypeArguments="x:String">
                        <On Platform="iOS" Value="NewJuneMedium" />
                    </OnPlatform>
                </Label.FontFamily>
            </Label>
</StackLayout>
    </Frame>

然后在您的基本内容页中,您可以添加以下代码,以在一段时间后显示和隐藏“toast”:

public async void showpopup(string msg)
    {
        await Navigation.PushPopupAsync(new Toast(msg));
        await Task.Delay(3000);
        await Navigation.PopPopupAsync(true);   
    }

0

您可以使用Xamarin.Toolkit并按照MS提供的信息进行操作。 https://learn.microsoft.com/en-us/xamarin/community-toolkit/views/popup

在我的应用程序中,我可以通过将每个代码部分放置在视图模型、视图和名为DismissThisPopup()的方法之间来管理它。因此,可以从当前Mainpage之外控制它。

为了实现您的请求, 您可以在调用popup.Open()之后调用await Task.Delay(5000); //例如5秒 这样它可能看起来像:

    ...
var vm = new MyPopUpViewModel()
vm.DisplayText = "this could be your text";
vm.DelayTimeForDismiss = 5000;
vm.IsLightDismissAllowed = false; //used that you can not close the popup by clicking around
await vm.OpenPopupAsync();

然后在您的虚拟机中打开OpenPopUpAsync()

...other properties and stuff
internal PopUpLoadingView popup = new PopUpLoadingView();//this is the view created with the informations from MS

public async Task OpenPopUp()
{
 popup.BindingContext = this;            
 Application.Current.MainPage.Navigation.ShowPopup(popup: popup);
 await Task.Delay(DelayTimeForDismiss);
 popup.DismissThisPopup();
}

在你的PopUpLoadingView中,插入这个方法:
...other stuff
        public void DismissThisPopup()
        {
            Dismiss(this);
        }

0

在添加Alex的代码时,针对UWP变体,我在这里找到了一个很棒的实现https://www.c-sharpcorner.com/article/xamarin/

来给他鼓掌吧 :)

[assembly:Xamarin.Forms.Dependency(typeof(Toast_UWP))]  
namespace ToastMessage.UWP  
{  
    class Toast_UWP : Toast  
    {  
        public void Show(string message)  
        {  
            ToastTemplateType toastTemplate = ToastTemplateType.ToastImageAndText01;  
            XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);  
  
            XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");  
            toastTextElements[0].AppendChild(toastXml.CreateTextNode(message));  
              
            XmlNodeList toastImageAttributes = toastXml.GetElementsByTagName("image");  
            ((XmlElement)toastImageAttributes[0]).SetAttribute("src", "ms-appx:///Assets/Logo.scale-240.png");  
            ((XmlElement)toastImageAttributes[0]).SetAttribute("alt", "logo");  
  
            IXmlNode toastNode = toastXml.SelectSingleNode("/toast");  
            ((XmlElement)toastNode).SetAttribute("duration", "short");  
  
            var toastNavigationUriString = "#/MainPage.xaml?param1=12345";  
            var toastElement = ((XmlElement)toastXml.SelectSingleNode("/toast"));  
            toastElement.SetAttribute("launch", toastNavigationUriString);  
  
            ToastNotification toast = new ToastNotification(toastXml);  
  
            ToastNotificationManager.CreateToastNotifier().Show(toast);  
        }  
    }  
}   

默认情况下,您的消息将按顺序排队,并根据消息持续时间延迟通知。如果您想立即用新消息替换现有消息,只需添加以下代码

ToastNotificationManager.History.Remove("YOUR_TAG");

// Code to create Toast message, like the above method

toast.Tag = "YOUR_TAG";

如果您想要在烤面包提示消息中添加音频,请将以下代码添加到您的代码中。
var audio = toastXml.CreateElement("audio");
audio.SetAttribute("src", "ms-winsoundevent:Notification.Default");

0

对于 UWP

public void ShowMessageFast(string message)
    {
        ToastNotifier ToastNotifier = ToastNotificationManager.CreateToastNotifier();
        Windows.Data.Xml.Dom.XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
        Windows.Data.Xml.Dom.XmlNodeList toastNodeList = toastXml.GetElementsByTagName("text");
        toastNodeList.Item(0).AppendChild(toastXml.CreateTextNode("Test"));
        toastNodeList.Item(1).AppendChild(toastXml.CreateTextNode(message));
        Windows.Data.Xml.Dom.IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
        Windows.Data.Xml.Dom.XmlElement audio = toastXml.CreateElement("audio");
        audio.SetAttribute("src", "ms-winsoundevent:Notification.SMS");

        ToastNotification toast = new ToastNotification(toastXml);
        toast.ExpirationTime = DateTime.Now.AddSeconds(4);
        ToastNotifier.Show(toast);
    }

0

上面的iOS答案对我有用,但有一个小问题--警告:尝试呈现UIAlertController...其视图不在窗口层次结构中!

经过一些搜索,我发现了这个无关的答案,它帮了我很大的忙。发布者评论说“这看起来很愚蠢,但却有效”,这两点都是正确的。

因此,我使用以下代码修改了上面的ShowAlert()函数,它们似乎可以正常工作:

    var rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController;
    while ( rootVC.PresentedViewController != null) {
        rootVC = rootVC.PresentedViewController;
    }
    rootVC.PresentViewController( alert, true, null);

当我看到下面@Pierre-Alexandre Flèche的更好版本时,我感到惊讶。我之前怎么错过了呢? - bobwki

0

安装nuget Acr.UserDialogs。 它包含Toasts,正是您所需要的。

ToastEvent toastEvent = new ToastEvent();
var toastConfig = new ToastConfig(toastEvent,"Toasting...","");
toastConfig.SetDuration(2000);

UserDialogs.Instance.Toast(toastConfig);

0

目前在Android中使用Xamarin Essential:

//access mainthread
MainThread.BeginInvokeOnMainThread(() =>
{
     Toast.MakeText(Application.Context, message, ToastLength.Short).Show();       
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接