Toast-equivalent voor Xamarin Forms

Is er een manier om Xamarin Forms (niet Android- of iOS-specifiek) te gebruiken om een ​​pop-up te krijgen, zoals Android doet met Toast, die geen gebruikersinteractie nodig heeft en na een (korte) tijd verdwijnt?

Het enige wat ik zie, zijn waarschuwingen waarvoor gebruikersklikken nodig zijn om te verdwijnen.


Antwoord 1, autoriteit 100%

Hier is een eenvoudige oplossing voor. Door de DependencyServicete gebruiken, kunt u eenvoudig de Toast-achtige aanpak in zowel Android als iOS.

Maak een interface in uw gemeenschappelijke pakket.

public interface IMessage
{
    void LongAlert(string message);
    void ShortAlert(string message);
}

Android-gedeelte

[assembly: Xamarin.Forms.Dependency(typeof(MessageAndroid))]
namespace Your.Namespace
{
    public class MessageAndroid : IMessage
    {
        public void LongAlert(string message)
        {
            Toast.MakeText(Application.Context, message, ToastLength.Long).Show();
        }
        public void ShortAlert(string message)
        {
            Toast.MakeText(Application.Context, message, ToastLength.Short).Show();
        }
    }
}

iOS-gedeelte

In iOs is er geen native oplossing zoals Toast, dus we moeten onze eigen aanpak implementeren.

[assembly: Xamarin.Forms.Dependency(typeof(MessageIOS))]
namespace Your.Namespace
{
    public class MessageIOS : IMessage
    {
        const double LONG_DELAY = 3.5;
        const double SHORT_DELAY = 2.0;
        NSTimer alertDelay;
        UIAlertController alert;
        public void LongAlert(string message)
        {
            ShowAlert(message, LONG_DELAY);
        }
        public void ShortAlert(string message)
        {
            ShowAlert(message, SHORT_DELAY);
        }
        void ShowAlert(string message, double seconds)
        {
            alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) =>
            {
                dismissMessage();
            });
            alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
            UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
        }
        void dismissMessage()
        {
            if (alert != null)
            {
                alert.DismissViewController(true, null);
            }
            if (alertDelay != null)
            {
                alertDelay.Dispose();
            }
        }
    }
}

Houd er rekening mee dat we op elk platform onze lessen moeten registreren bij DependencyService.

Je hebt nu overal in ons project toegang tot onze Toast-service.

DependencyService.Get<IMessage>().ShortAlert(string message); 
DependencyService.Get<IMessage>().LongAlert(string message);

Antwoord 2, autoriteit 9%

Hier is een versie van Alex Chengalan’s iOS codedie voorkomt dat de gebruikersinterface blijft hangen wanneer meerdere berichten worden weergegeven…

public class MessageIOS : IMessage
    {
        const double LONG_DELAY = 3.5;
        const double SHORT_DELAY = 0.75;
        public void LongAlert(string message)
        {
            ShowAlert(message, LONG_DELAY);
        }
        public void ShortAlert(string message)
        {
            ShowAlert(message, SHORT_DELAY);
        }
        void ShowAlert(string message, double seconds)
        {
            var alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
            var alertDelay = NSTimer.CreateScheduledTimer(seconds, obj =>
            {
                DismissMessage(alert, obj);
            });
            UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
        }
        void DismissMessage(UIAlertController alert, NSTimer alertDelay)
        {
            if (alert != null)
            {
                alert.DismissViewController(true, null);
            }
            if (alertDelay != null)
            {
                alertDelay.Dispose();
            }
        }
    }

Antwoord 3, autoriteit 8%

U kunt het Acr.UserDialogs-pakket gebruiken van nuget en code zoals hieronder,

Acr.UserDialogs.UserDialogs.Instance.Toast(Message, new TimeSpan(3));

Antwoord 4, autoriteit 4%

Als aanvulling op het antwoord van Alex, hier is de UWP-variant:

public class Message : IMessage {
  private const double LONG_DELAY = 3.5;
  private const double SHORT_DELAY = 2.0;
  public void LongAlert(string message) =>
    ShowMessage(message, LONG_DELAY);
  public void ShortAlert(string message) =>
    ShowMessage(message, SHORT_DELAY);
  private void ShowMessage(string message, double duration) {
    var label = new TextBlock {
      Text = message,
      Foreground = new SolidColorBrush(Windows.UI.Colors.White),
      HorizontalAlignment = HorizontalAlignment.Center,
      VerticalAlignment = VerticalAlignment.Center,
    };
    var style = new Style { TargetType = typeof(FlyoutPresenter) };
    style.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Windows.UI.Colors.Black)));
    style.Setters.Add(new Setter(FrameworkElement.MaxHeightProperty, 1));
    var flyout = new Flyout {
      Content = label,
      Placement = FlyoutPlacementMode.Full,
      FlyoutPresenterStyle = style,
    };
    flyout.ShowAt(Window.Current.Content as FrameworkElement);
    var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(duration) };
    timer.Tick += (sender, e) => {
      timer.Stop();
      flyout.Hide();
    };
    timer.Start();
  }
}

Kleur en styling is aan jou, de MaxHeightis eigenlijk vereist om de hoogte minimaal te houden.


Antwoord 5, autoriteit 4%

Je kunt SnackBargebruiken uit de Xamarin Community-toolkitpakket, dat native implementatie gebruikt in platforms waar native ondersteund, omdat Toastis verouderd in API-niveau 30, een SnackBarzonder een Actie is gelijk aan een Toast.

Deze methode is beëindigd in API-niveau 30.
Aangepaste toastweergaven zijn verouderd. Apps kunnen een standaard teksttoast maken met de makeText(android.content.Context, java.lang.CharSequence, int) methode, of een Snackbar gebruiken op de voorgrond. Vanaf Android Build.VERSION_CODES#R zullen apps die zich op API-niveau Build.VERSION_CODES#R of hoger richten en die zich op de achtergrond bevinden, geen aangepaste toastweergaven weergeven. (bron).

Begin met Xamarin Community-toolkit

  1. Installeer het pakket op al uw projecten
  2. neem de naamruimte using Xamarin.CommunityToolkit.Extensions;
  3. In uw pagina code-behind toon een SnackBar bij een evenement
await this.DisplayToastAsync("This is a Toast Message");
await this.DisplayToastAsync("This is a Toast Message for 5 seconds", 5000);

U kunt een duur specificeren voor het verdwijnen van de SnackBar (in milliseconden) of de standaardwaarde laten die gelijk is aan 3 seconden.

voer hier de afbeeldingsbeschrijving in


Bronnen

SnackBar-voorbeeld

Officiële repohttps://github.com/xamarin/XamarinCommunityToolkit

Officiële documentenhttps://docs .microsoft.com/en-us/xamarin/community-toolkit/


BEWERKEN

  1. Verankerde toast:je kunt de toast boven een weergave verankeren (zoals screenshot hierboven) door in plaats daarvan de extensiemethode DisplayToastAsync()aan te roepen vanuit dat weergaveobject (anker). van de pagina-instantie (this):
<Button x:name="floatingButton" .../>
await floatingButton.DisplayToastAsync("This is a Toast Message for 5 seconds", 5000);
  1. Opvulling en hoekradius:(vanaf xct-versie 1.3.0 preview-1)

Je kunt de hoekradius en de opvulling voor je Toast instellen zoals in het volgende voorbeeld:

var messageOptions = new MessageOptions
{
    Message = "Toast with Padding and round corner",
    Foreground = Color.White,
    Font = Font.SystemFontOfSize(16),
    Padding = new Thickness(20)
};
var options = new ToastOptions
    {
        MessageOptions = messageOptions,
        CornerRadius = new Thickness(40, 40, 0, 0),
        BackgroundColor = Color.FromHex("#CC0000")
    };
await this.DisplayToastAsync(options);

voer hier de afbeeldingsbeschrijving in

voer hier de afbeeldingsbeschrijving in

PS: Dezelfde eigenschappen kunnen worden toegepast op de SnackBar-weergave.


Antwoord 6, autoriteit 4%

Normaal zouden we de plug-in Egors Toasts gebruiken, maar omdat het voor een huidig ​​project machtigingen op iOS vereist, zijn we een andere weg ingeslagen met behulp van Rg.Plugins.Popupnuget (https://github.com/rotorgames/Rg.Plugins.Popup).

Ik heb een standaard xaml/cs-pagina van het type PopupPage geschreven,

<?xml version="1.0" encoding="utf-8" ?>
<popup:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:popup="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
         x:Class="YourApp.Controls.ToastPage">
...

en het laten maken door een service waarvan u de interface hebt geregistreerd bij het starten van de app of Xamarin.Forms.DependencyServicegebruikt om de service op te halen, zou ook haalbaar zijn.

Het servicenieuws op de van PopupPage afgeleide pagina, en doet

await PopupNavigation.PushAsync(newToastPage);
await Task.Delay(2000);
await PopupNavigation.PopAllAsync();

De pop-uppagina kan door de gebruiker worden gesloten door buiten de paginaweergave te tikken (ervan uitgaande dat deze het scherm niet heeft gevuld).

Dit lijkt prima te werken op iOS/Droid, maar ik sta open voor correctie als iemand weet wat dit een riskante manier is om het te doen.


Antwoord 7, autoriteit 3%

U kunt IUserDialog NuGetgebruiken en gewoon de toastAlert gebruiken

var toastConfig = new ToastConfig("Toasting...");
toastConfig.SetDuration(3000);
toastConfig.SetBackgroundColor(System.Drawing.Color.FromArgb(12, 131, 193));
UserDialogs.Instance.Toast(toastConfig);

Antwoord 8, autoriteit 2%

Hier is een codefragment dat ik gebruik om de toast in Xamarin.iOS te laten zien

 public void ShowToast(String message, UIView view)
    {
        UIView residualView = view.ViewWithTag(1989);
        if (residualView != null)
            residualView.RemoveFromSuperview();
        var viewBack = new UIView(new CoreGraphics.CGRect(83, 0, 300, 100));
        viewBack.BackgroundColor = UIColor.Black;
        viewBack.Tag = 1989;
        UILabel lblMsg = new UILabel(new CoreGraphics.CGRect(0, 20, 300, 60));
        lblMsg.Lines = 2;
        lblMsg.Text = message;
        lblMsg.TextColor = UIColor.White;
        lblMsg.TextAlignment = UITextAlignment.Center;
        viewBack.Center = view.Center;
        viewBack.AddSubview(lblMsg);
        view.AddSubview(viewBack);
        roundtheCorner(viewBack);
        UIView.BeginAnimations("Toast");
        UIView.SetAnimationDuration(3.0f);
        viewBack.Alpha = 0.0f;
        UIView.CommitAnimations();
    }

Antwoord 9, autoriteit 2%

Ik zou de bibliotheek Plugin.Toastvan nugetaanbevelen. Het werkt goed.

CrossToastPopUp.Current.ShowToastMessage("my toast message");

of van ACR.UserDialogs Nuget-bibliotheek

UserDialogs.Instance.ShowLoading("Loading");

Antwoord 10, autoriteit 2%

@MengTim, om het probleem met meerdere toast in de oplossing van @alex-chengalan op te lossen, heb ik alles eenvoudig in ShowAlert()verpakt met een vinkje om te zien of alerten alertDelayzijn null, en binnen DismissMessageworden alerten alertDelayongeldig gemaakt.

void ShowAlert(string message, double seconds)
    {
        if(alert == null && alertDelay == null) {
            alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) =>
            {
                DismissMessage();
            });
            alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
            UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
        }
    }
    void DismissMessage()
    {
        if (alert != null)
        {
            alert.DismissViewController(true, null);
            alert = null;
        }
        if (alertDelay != null)
        {
            alertDelay.Dispose();
            alertDelay = null;
        }
    }

Dat leek in ieder geval het vastlopen van de gebruikersinterface op te lossen, als je op zoek bent naar een snelle oplossing. Ik probeerde de toast op navigatie naar een nieuwe pagina weer te geven en geloofde dat de PresentViewControllerdie werd ingesteld mijn navigatie in wezen annuleerde. Sorry dat ik geen commentaar heb gegeven in de thread, mijn reputatie is te laag 🙁


Antwoord 11

Dit is mijn verbeterde ShowAlert-versie van Ian Warburtons versie om ervoor te zorgen dat de toast zelfs op de pop-uppagina wordt weergegeven.
Verder wordt de toast verwijderd als de gebruiker buiten de toast klikt.
Ik gebruikte UIAlertControllerStyle.ActionSheetdat op toast lijkt, maar het werkt ook met 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);
        });
    }

Ik hoop dat dit iemand zal helpen!


Antwoord 12

Er is geen ingebouwd mechanisme in Forms, maar dit nugetpakket levert iets soortgelijks

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

Opmerking: dit zijn geen toasts in Android-stijl zoals gevraagd in de vraag, maar toasts in UWP-stijl die systeembrede meldingen zijn.


Antwoord 13

Ik heb een aangepaste pop-up aangepast met Rg.Plugins.Popup NuGet
dit is een voorbeeld:

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

dan kun je in je basecontentpagina de volgende code toevoegen om de “toast” na een tijdje te tonen en te verbergen:

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

Antwoord 14

Ik gebruikte
https://github.com/ishrakland/Toast/
In
https://www.nuget.org/packages/Plugin.Toast/

Voorbeeld:

CrossToastPopUp.Current.ShowToastMessage ("Loading", Plugin.Toast.Abstractions.ToastLength.Short);

Probeer het eens.


Antwoord 15

De bovenstaande iOS-antwoorden werkten voor mij, maar voor een klein probleem: een waarschuwing: probeer UIalertController te presenteren … wiens weergave niet in de vensterhiërarchie staat!

Na wat zoeken kwam ik dit niet-gerelateerde antwoordtegen dat hielp. De poster merkte op: “Dit ziet er stom uit, maar werkt”, wat in beide opzichten juist is.

Dus ik heb de functie ShowAlert() hierboven aangepast met deze regels, die lijken te werken:

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

Antwoord 16

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

Antwoord 17

Gebruik momenteel xamarin essential in Android:

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

Antwoord 18

Door Alex’ code toe te voegen, voor de UWP-variant, vond ik hier een geweldige implementatie
https://www.c-sharpcorner.com/article/xamarin/

Kom gewoon een klap voor hem achterlaten 🙂

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

Standaard worden uw berichten in de wachtrij geplaatst en één voor één op de hoogte gebracht, vertraagd op basis van de berichtduur. Als u het bestaande bericht onmiddellijk door het nieuwe wilt vervangen, voegt u gewoon meer code toe zoals hieronder

ToastNotificationManager.History.Remove("YOUR_TAG");
// Code to create Toast message, like the above method
toast.Tag = "YOUR_TAG";

Als je audio aan je toastbericht wilt toevoegen, voeg dit dan toe aan je code

var audio = toastXml.CreateElement("audio");
audio.SetAttribute("src", "ms-winsoundevent:Notification.Default");

Antwoord 19

Installeer nuget Acr.UserDialogs.
Het bevat Toastsprecies wat u zoekt.

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

Antwoord 20

U kunt DisplayAlert("", "", "", "" );

gebruiken

Other episodes