มีวิธีใดบ้างที่ใช้ Xamarin Forms (ไม่ใช่เฉพาะ Android หรือ iOS) เพื่อให้มีป๊อปอัปเช่น Android ทำกับ Toast ที่ไม่ต้องใช้การโต้ตอบกับผู้ใช้และหายไปหลังจากช่วงเวลาสั้น ๆ
จากการค้นหารอบ ๆ ทั้งหมดที่ฉันเห็นคือการแจ้งเตือนที่ต้องการให้ผู้ใช้คลิกจึงจะหายไป
มีวิธีใดบ้างที่ใช้ Xamarin Forms (ไม่ใช่เฉพาะ Android หรือ iOS) เพื่อให้มีป๊อปอัปเช่น Android ทำกับ Toast ที่ไม่ต้องใช้การโต้ตอบกับผู้ใช้และหายไปหลังจากช่วงเวลาสั้น ๆ
จากการค้นหารอบ ๆ ทั้งหมดที่ฉันเห็นคือการแจ้งเตือนที่ต้องการให้ผู้ใช้คลิกจึงจะหายไป
คำตอบ:
มีวิธีง่ายๆสำหรับเรื่องนี้ ด้วยการใช้DependencyServiceคุณสามารถรับวิธีการ Toast-Like ได้อย่างง่ายดายทั้งใน Android และ iOS
สร้างอินเทอร์เฟซในแพ็คเกจทั่วไปของคุณ
public interface IMessage
{
void LongAlert(string message);
void ShortAlert(string message);
}
ส่วน 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();
}
}
}
ส่วน iOS
ใน iOs ไม่มีโซลูชันดั้งเดิมเช่น Toast ดังนั้นเราจึงต้องใช้แนวทางของเราเอง
[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();
}
}
}
}
โปรดทราบว่าในแต่ละแพลตฟอร์มเราต้องลงทะเบียนชั้นเรียนของเรากับ DependencyService
ตอนนี้คุณสามารถเข้าถึงบริการ Toast ได้จากทุกที่ในโครงการของเรา
DependencyService.Get<IMessage>().ShortAlert(string message);
DependencyService.Get<IMessage>().LongAlert(string message);
DismissMessageทั้งสองจะต้องมีการส่งผ่านไปยัง
นี่คือรหัส iOS ของ Alex Chengalan ที่หลีกเลี่ยงการติด UI เมื่อมีการแสดงข้อความหลายข้อความ ...
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();
}
}
}
คุณสามารถใช้ Acr.UserDialogs Package จาก nuget และรหัสด้านล่าง
Acr.UserDialogs.UserDialogs.Instance.Toast(Message, new TimeSpan(3));
โดยปกติเราจะใช้ปลั๊กอิน Egors Toasts แต่เนื่องจากต้องใช้สิทธิ์บน iOS สำหรับโปรเจ็กต์ปัจจุบันเราจึงใช้เส้นทางอื่นโดยใช้ Rg.Plugins.Popup nuget ( https://github.com/rotorgames/Rg.Plugins.Popup ).
ฉันเขียนหน้า xaml / cs พื้นฐานประเภท 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">
...
และสร้างขึ้นโดยบริการซึ่งมีอินเทอร์เฟซที่คุณลงทะเบียนเมื่อเริ่มต้นแอปหรือใช้ Xamarin.Forms.DependencyService เพื่อดึงข้อมูลบริการก็ทำได้เช่นกัน
ข่าวบริการขึ้นหน้ามา PopupPage และทำ
await PopupNavigation.PushAsync(newToastPage);
await Task.Delay(2000);
await PopupNavigation.PopAllAsync();
ผู้ใช้สามารถปิดหน้าป๊อปอัปได้โดยแตะที่ด้านนอกของการแสดงเพจ (สมมติว่ายังไม่เต็มหน้าจอ)
ดูเหมือนว่าจะทำงานได้อย่างมีความสุขบน iOS / Droid แต่ฉันยินดีที่จะแก้ไขหากใครรู้ว่าวิธีนี้เป็นวิธีที่เสี่ยง
การเพิ่มคำตอบของ Alex นี่คือตัวแปร 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();
}
}
การระบายสีและการจัดแต่งทรงผมขึ้นอยู่กับคุณMaxHeightจำเป็นต้องรักษาความสูงให้ต่ำที่สุด
คุณสามารถใช้ IUserDialog NuGetและใช้เพียงแค่ toastAlert
var toastConfig = new ToastConfig("Toasting...");
toastConfig.SetDuration(3000);
toastConfig.SetBackgroundColor(System.Drawing.Color.FromArgb(12, 131, 193));
UserDialogs.Instance.Toast(toastConfig);
นี่คือข้อมูลโค้ดที่ฉันใช้เพื่อแสดงขนมปังปิ้งใน 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();
}
ฉันจะแนะนำห้องสมุดจากPlugin.Toast nugetมันทำงานได้ดี
CrossToastPopUp.Current.ShowToastMessage("my toast message");
หรือจาก ACR.UserDialogs Nuget libriary
UserDialogs.Instance.ShowLoading("Loading");
@MengTim เพื่อแก้ไขปัญหาขนมปังหลายชิ้นในวิธีแก้ปัญหาของ @ alex-chengalan ฉันเพียงแค่ห่อทุกอย่างไว้ภายในShowAlert()ด้วยการตรวจสอบเพื่อดูว่าalertและalertDelayเป็นโมฆะจากนั้นภายในลบDismissMessageออกalertและalertDelay.
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;
}
}
ดูเหมือนว่าอย่างน้อยจะล้าง UI ค้างหากคุณกำลังมองหาการแก้ไขอย่างรวดเร็ว ฉันพยายามแสดงขนมปังปิ้งบนการนำทางไปยังหน้าใหม่และเชื่อว่าPresentViewControllerการตั้งค่านั้นกำลังยกเลิกการนำทางของฉันเป็นหลัก ขออภัยฉันไม่ได้แสดงความคิดเห็นในกระทู้ชื่อเสียงของฉันต่ำเกินไป :(
นี่เป็นShowAlertเวอร์ชันปรับปรุงของ Ian Warburton เพื่อให้แน่ใจว่าขนมปังปิ้งจะแสดงแม้ในหน้าป๊อปอัป นอกจากนี้ขนมปังปิ้งจะหายไปหากผู้ใช้คลิกนอกขนมปังปิ้ง ฉันใช้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);
});
}
ฉันหวังว่านี่จะช่วยใครสักคน!
ไม่มีกลไกในตัวในฟอร์ม แต่แพ็กเกจนักเก็ตนี้ให้สิ่งที่คล้ายกัน
https://github.com/EgorBo/Toasts.Forms.Plugin
หมายเหตุ: นี่ไม่ใช่โทสต์สไตล์ Android ตามที่ร้องขอในคำถาม แต่เป็นโทสต์สไตล์ UWP ซึ่งเป็นการแจ้งเตือนทั้งระบบ
ฉันใช้ https://github.com/ishrakland/Toast/ ใน https://www.nuget.org/packages/Plugin Toast/
ตัวอย่าง CrossToastPopUp.Current.ShowToastMessage ("กำลังโหลด", Plugin Toast.Abstractions ToastLength.Short);
ลองแล้วมันเยี่ยมมาก
ฉันปรับแต่งป๊อปอัปแบบกำหนดเองด้วย 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>
จากนั้นในหน้าหลักของคุณคุณสามารถเพิ่มรหัสต่อไปนี้เพื่อแสดงและซ่อน "ขนมปังปิ้ง" หลังจากนั้นสักครู่:
public async void showpopup(string msg)
{
await Navigation.PushPopupAsync(new Toast(msg));
await Task.Delay(3000);
await Navigation.PopPopupAsync(true);
}
คำตอบ iOS ข้างต้นใช้ได้ผลสำหรับฉัน แต่สำหรับปัญหาเล็กน้อย - คำเตือน: พยายามนำเสนอ UIAlertController ... ซึ่งมุมมองไม่ได้อยู่ในลำดับชั้นของหน้าต่าง!
หลังจากการค้นหาฉันพบคำตอบที่ไม่เกี่ยวข้องซึ่งช่วยได้ ผู้โพสต์ให้ความเห็นว่า "มันดูโง่ แต่ใช้งานได้" ซึ่งถูกต้องทั้งสองข้อ
ดังนั้นฉันจึงแก้ไขฟังก์ชัน ShowAlert () ด้านบนด้วยบรรทัดเหล่านี้ซึ่งดูเหมือนจะใช้งานได้:
var rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController;
while ( rootVC.PresentedViewController != null) {
rootVC = rootVC.PresentedViewController;
}
rootVC.PresentViewController( alert, true, null);
สำหรับ 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);
}
คุณสามารถใช้ได้ DisplayAlert("", "", "", "" );