Jest na to proste rozwiązanie. Korzystając z DependencyService , możesz łatwo uzyskać podejście Toast-Like w systemie Android i iOS.
Utwórz interfejs w swoim wspólnym pakiecie.
public interface IMessage
{
void LongAlert(string message);
void ShortAlert(string message);
}
Sekcja Android
[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();
}
}
}
sekcja iOS
W iOs nie ma natywnego rozwiązania takiego jak Toast, więc musimy wdrożyć własne podejście.
[assembly: Xamarin.Forms.Dependency(typeof(MessageIOS))]
namespace Bahwan.iOS
{
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();
}
}
}
}
Należy pamiętać, że na każdej platformie musimy zarejestrować nasze klasy w DependencyService.
Teraz możesz uzyskać dostęp do usługi Toast w dowolnym miejscu naszego projektu.
DependencyService.Get<IMessage>().ShortAlert(string message);
DependencyService.Get<IMessage>().LongAlert(string message);
DismissMessage
.Oto wersja kodu iOS Alexa Chengalana, która pozwala uniknąć przyklejania się interfejsu użytkownika, gdy wyświetlanych jest wiele wiadomości ...
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(); } } }
źródło
Możesz użyć pakietu Acr.UserDialogs z nuget i kodu jak poniżej,
Acr.UserDialogs.UserDialogs.Instance.Toast(Message, new TimeSpan(3));
źródło
Zwykle używamy wtyczki Egors Toasts, ale ponieważ wymaga ona uprawnień na iOS dla bieżącego projektu, poszliśmy inną drogą za pomocą Rg.Plugins.Popup nuget ( https://github.com/rotorgames/Rg.Plugins.Popup ).
Napisałem podstawową stronę xaml / cs typu PopupPage,
<?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"> ...
i mieć go utworzonego przez usługę, której interfejs rejestrujesz podczas uruchamiania aplikacji lub używasz Xamarin.Forms.DependencyService do pobierania usługi, również byłby opłacalny.
Usługa wysyła wiadomości na stronę pochodną PopupPage i robi
await PopupNavigation.PushAsync(newToastPage); await Task.Delay(2000); await PopupNavigation.PopAllAsync();
Strona Popup może zostać zamknięta przez użytkownika, dotykając poza wyświetlaną stroną (zakładając, że nie wypełniła ekranu).
Wydaje się, że działa to szczęśliwie na iOS / Droid, ale jestem otwarty na korektę, jeśli ktoś wie, co to jest ryzykowny sposób robienia tego.
źródło
Dodając do odpowiedzi Alexa, oto wariant UWP:
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(); } }
Kolorystyka i stylizacja zależy od Ciebie, w
MaxHeight
rzeczywistości jest to wymagane, aby utrzymać minimalną wysokość.źródło
Możesz użyć IUserDialog NuGet i po prostu użyć jego toastAlert
var toastConfig = new ToastConfig("Toasting..."); toastConfig.SetDuration(3000); toastConfig.SetBackgroundColor(System.Drawing.Color.FromArgb(12, 131, 193)); UserDialogs.Instance.Toast(toastConfig);
źródło
Oto fragment kodu, którego używam, aby pokazać toast w Xamarin.iOS
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(); }
źródło
Polecam
Plugin.Toast
bibliotekę odnuget
. To dobrze działa.CrossToastPopUp.Current.ShowToastMessage("my toast message");
lub z biblioteki ACR.UserDialogs Nuget
UserDialogs.Instance.ShowLoading("Loading");
źródło
@MengTim, aby naprawić problem z wieloma tostami w rozwiązaniu @ alex-chengalan, po prostu zawinąłem wszystko w środku
ShowAlert()
czekiem, aby sprawdzić, czyalert
ialertDelay
są zerowe, a następnie wDismissMessage
środku, anulowanealert
ialertDelay
.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; } }
Wydawało się, że przynajmniej poprawiło to zawieszenie interfejsu użytkownika, jeśli szukasz szybkiego rozwiązania. Próbowałem wyświetlić toast po przejściu do nowej strony i wierzę,
PresentViewController
że ustawienie zasadniczo przerywa moją nawigację. Przepraszam, że nie komentowałem w wątku, moja reputacja jest zbyt niska :(źródło
W Forms nie ma wbudowanego mechanizmu, ale ten pakiet NuGet dostarcza coś podobnego
https://github.com/EgorBo/Toasts.Forms.Plugin
Uwaga: to nie są tosty w stylu Androida, jak żądano w pytaniu, ale toasty w stylu UWP, które są powiadomieniami w całym systemie.
źródło
To jest moja ulepszona
ShowAlert
wersja wersji Iana Warburtona, która zapewnia wyświetlanie toastu nawet na wyskakującej stronie. Ponadto toast jest odrzucany, jeśli użytkownik kliknie poza toastem. Użyłem,UIAlertControllerStyle.ActionSheet
że wygląda jak tosty, ale też działaUIAlertControllerStyle.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); }); }
Mam nadzieję, że to komuś pomoże!
źródło
Używam https://github.com/ishrakland/Toast/ w https://www.nuget.org/packages/Plugin.Toast/
Przykład CrossToastPopUp.Current.ShowToastMessage ("Loading", Plugin.Toast.Abstractions.ToastLength.Short);
Spróbuj, to świetnie
źródło
Dostosowałem niestandardowe wyskakujące okienko za pomocą Rg.Plugins.Popup NuGet. Oto przykład:
<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>
następnie na swojej podstawowej stronie możesz dodać następujący kod, aby po chwili pokazać i ukryć „toast”:
public async void showpopup(string msg) { await Navigation.PushPopupAsync(new Toast(msg)); await Task.Delay(3000); await Navigation.PopPopupAsync(true); }
źródło
Powyższe odpowiedzi na iOS działały dla mnie, ale z jednym małym problemem - ostrzeżenie: próba zaprezentowania UIAlertController ... którego widok nie znajduje się w hierarchii okien!
Po kilku poszukiwaniach natknąłem się na tę niepowiązaną odpowiedź, która pomogła. Plakat skomentował: „To wygląda głupio, ale działa”, co jest słuszne w obu przypadkach.
Tak więc zmodyfikowałem powyższą funkcję ShowAlert () za pomocą tych linii, które wydają się działać:
var rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController; while ( rootVC.PresentedViewController != null) { rootVC = rootVC.PresentedViewController; } rootVC.PresentViewController( alert, true, null);
źródło
W przypadku 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); }
źródło
Możesz użyć
DisplayAlert("", "", "", "" );
źródło