Ada solusi sederhana untuk ini. Dengan menggunakan DependencyService, Anda bisa dengan mudah mendapatkan pendekatan Toast-Like di Android dan iOS.
Buat antarmuka dalam paket umum Anda.
public interface IMessage
{
void LongAlert(string message);
void ShortAlert(string message);
}
Bagian 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();
}
}
}
Bagian iOS
Di iOs tidak ada solusi asli seperti Toast, jadi kami perlu menerapkan pendekatan kami sendiri.
[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();
}
}
}
}
Please note that in each platform, we have to register our classes with DependencyService.
Now you can access out Toast service in anywhere in our project.
DependencyService.Get<IMessage>().ShortAlert(string message);
DependencyService.Get<IMessage>().LongAlert(string message);
DismissMessage
.Here's a version of Alex Chengalan's iOS code that avoids the UI sticking when multiple messages are shown...
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(); } } }
sumber
You can use Acr.UserDialogs Package from nuget and code like below,
Acr.UserDialogs.UserDialogs.Instance.Toast(Message, new TimeSpan(3));
sumber
We'd normally use Egors Toasts plugin, but as it requires permissions on iOS for a current project we've gone a different route using Rg.Plugins.Popup nuget (https://github.com/rotorgames/Rg.Plugins.Popup).
I wrote a basic xaml/cs page of type 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"> ...
and have it created by a service, whose interface you register at app start or use Xamarin.Forms.DependencyService to fetch the service would be viable too.
The service news up the PopupPage derived page, and does
await PopupNavigation.PushAsync(newToastPage); await Task.Delay(2000); await PopupNavigation.PopAllAsync();
The Popup page can be dismissed by the user by tapping outside the page display (assuming it hasn't filled the screen).
This seems to work happily on iOS/Droid, but I'm open to correction if anyone knows what this is a risky way of doing it.
sumber
Adding to Alex's answer, here's the 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(); } }
Coloring and styling is up to you, the
MaxHeight
is actually required to keep the height at the minimum.sumber
You can use IUserDialog NuGet and simply use it's toastAlert
var toastConfig = new ToastConfig("Toasting..."); toastConfig.SetDuration(3000); toastConfig.SetBackgroundColor(System.Drawing.Color.FromArgb(12, 131, 193)); UserDialogs.Instance.Toast(toastConfig);
sumber
Here is a code snippet that I am using to show the toast in 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(); }
sumber
I would recommend
Plugin.Toast
library fromnuget
. It works well.CrossToastPopUp.Current.ShowToastMessage("my toast message");
or from ACR.UserDialogs Nuget libriary
UserDialogs.Instance.ShowLoading("Loading");
sumber
@MengTim, to fix the multiple toast issue in @alex-chengalan's solution, I simply wrapped everything within
ShowAlert()
with a check to see ifalert
andalertDelay
are null, then withinDismissMessage
, nulled outalert
andalertDelay
.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; } }
That seemed to at least clear up the UI hang, if you are looking for a quick fix. I was trying to display the toast on navigation to a new page, and believe that the
PresentViewController
being set was essentially cancelling out my navigation. Sorry I did not comment within the thread, my reputation is too low :(sumber
This is my improved
ShowAlert
version of Ian Warburton's version to ensure that the toast is displayed even on popup page. Furthermore, the toast is dissmissed if the user click outside the toast. I usedUIAlertControllerStyle.ActionSheet
that look likes toast but it also work withUIAlertControllerStyle.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); }); }
I hope this will help someone !
sumber
There is no built-in mechanism in Forms, but this nuget package supplies something similar
https://github.com/EgorBo/Toasts.Forms.Plugin
Note: These are not Android style toasts as requested in the question but UWP style toasts which are system wide notifications.
sumber
I use https://github.com/ishrakland/Toast/ In https://www.nuget.org/packages/Plugin.Toast/
Example CrossToastPopUp.Current.ShowToastMessage ("Loading", Plugin.Toast.Abstractions.ToastLength.Short);
Try it, it's great
sumber
I customised a custom popup with Rg.Plugins.Popup NuGet this is an example:
<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>
then in your basecontentpage you can add the following code, to show and hide the "toast" after a while:
public async void showpopup(string msg) { await Navigation.PushPopupAsync(new Toast(msg)); await Task.Delay(3000); await Navigation.PopPopupAsync(true); }
sumber
The iOS answers above worked for me but for one little problem -- a warning: Attempt to present UIAlertController ... whose view is not in the window hierarchy!
After some search, I came across this unrelated answer which helped. The poster commented "This looks stupid but works", which is right on both counts.
So, I modified the ShowAlert() function above with these lines, which seem to work:
var rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController; while ( rootVC.PresentedViewController != null) { rootVC = rootVC.PresentedViewController; } rootVC.PresentViewController( alert, true, null);
sumber
For 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); }
sumber
You can use
DisplayAlert("", "", "", "" );
sumber