Xamarin Forms的Toast等效物

Jim*_*mmy 61 c# toast xamarin xamarin.forms

是否有任何方法使用Xamarin Forms(不是Android或iOS特定的)来弹出,就像Android与Toast一样,不需要用户交互,并在一段(短)时间后消失?

从搜索所有我看到的是需要用户点击消失的警报.

Ale*_*lan 128

有一个简单的解决方案.通过使用DependencyService,您可以轻松地在Android和iOS中获得Toast-Like方法.

在公共包中创建一个接口.

public interface IMessage
{
    void LongAlert(string message);
    void ShortAlert(string message);
}
Run Code Online (Sandbox Code Playgroud)

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,在每个平台中,我们必须使用DependencyService注册我们的类.

现在,您可以在我们项目的任何位置访问Toast服务.

DependencyService.Get<IMessage>().ShortAlert(string message); 
DependencyService.Get<IMessage>().LongAlert(string message);
Run Code Online (Sandbox Code Playgroud)

  • 这是迄今为止这个问题的最佳答案.不需要第三方插件或库. (14认同)
  • 是的,这是迄今为止最好的答案,我喜欢依赖服务 (5认同)
  • @JoycedeLanna 不要忘记在“MainActivity.cs”中**注册**接口。在 `LoadApplication(new App())` `DependencyService.Register&lt;IMessage, MessageAndroid&gt;();` 之前添加这行代码 (4认同)
  • 在DependencyService行中,我得到"对象引用未设置为对象的实例". (2认同)
  • 满怀胜利。您是否也有该版本的 UWP 版本? (2认同)

KiS*_*OrE 12

您可以使用nuget 中的 Acr.UserDialogs包和如下代码,

Acr.UserDialogs.UserDialogs.Instance.Toast(Message, new TimeSpan(3));
Run Code Online (Sandbox Code Playgroud)


Ian*_*ton 11

这是Alex Chengalan的iOS 代码版本,可以避免在显示多条消息时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();
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)


小智 9

我们通常使用 Egors Toasts 插件,但由于它需要 iOS 上当前项目的权限,我们使用Rg.Plugins.Popupnuget ( https://github.com/rotorgames/Rg.Plugins.Popup )走了一条不同的路线。

我写了一个 PopupPage 类型的基本 xaml/cs 页面,

<?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">
...
Run Code Online (Sandbox Code Playgroud)

并由服务创建,您在应用程序启动时注册的接口或用于Xamarin.Forms.DependencyService获取服务的接口也是可行的。

该服务将 PopupPage 派生页面消息上传,并执行

await PopupNavigation.PushAsync(newToastPage);
await Task.Delay(2000);
await PopupNavigation.PopAllAsync();
Run Code Online (Sandbox Code Playgroud)

用户可以通过在页面显示之外点击来关闭弹出页面(假设它没有填满屏幕)。

这似乎在 iOS/Droid 上运行良好,但如果有人知道这是一种冒险的做法,我愿意纠正。


Gáb*_*bor 8

除了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();
  }
}
Run Code Online (Sandbox Code Playgroud)

颜色和样式取决于您,MaxHeight实际上需要将高度保持在最低水平。


Cfu*_*fun 7

您可以使用SnackBar来自Xamarin 社区工具包包,该包在本机支持的平台中使用本机实现,因为Toast在 API 级别 30 中已弃用,SnackBar没有 Action 相当于 Toast。

此方法在 API 级别 30 中已弃用。自定义 Toast 视图已弃用。应用程序可以使用 makeText(android.content.Context, java.lang.CharSequence, int) 方法创建标准文本 toast,或者在前台使用 Snackbar。从 Android Build.VERSION_CODES#R 开始,在后台面向 API 级别 Build.VERSION_CODES#R 或更高级别的应用将不会显示自定义 Toast 视图。(来源)。

从 Xamarin 社区工具包开始

  1. 在所有项目上安装包
  2. 包括命名空间 using Xamarin.CommunityToolkit.Extensions;
  3. 在您的页面代码隐藏中,在事件发生时显示 SnackBar
await this.DisplayToastAsync("This is a Toast Message");
await this.DisplayToastAsync("This is a Toast Message for 5 seconds", 5000);
Run Code Online (Sandbox Code Playgroud)

您可以指定 SnackBar 消失的持续时间(以毫秒为单位)或保留默认值,即 3 秒。

在此处输入图片说明


资源

小吃店样品

官方回购 https://github.com/xamarin/XamarinCommunityToolkit

官方文档 https://docs.microsoft.com/en-us/xamarin/community-toolkit/


编辑

  1. 锚定 Toast:您可以通过简单地DisplayToastAsync()从该视图(锚点)对象而不是从页面实例 ( this)调用扩展方法来将 toast 锚定在视图上方(如上面的屏幕截图):
<Button x:name="floatingButton" .../>

await floatingButton.DisplayToastAsync("This is a Toast Message for 5 seconds", 5000);
Run Code Online (Sandbox Code Playgroud)
  1. 填充和圆角半径:(从 xct version 1.3.0 preview-1 开始)

您可以为 Toast 设置圆角半径和内边距,如下例所示:

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);
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

在此处输入图片说明

PS:可以为SnackBar视图应用相同的属性。


moh*_*ali 6

您可以使用 IUserDialog NuGet并简单地使用它的 toastAlert

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

UserDialogs.Instance.Toast(toastConfig);
Run Code Online (Sandbox Code Playgroud)


Jas*_*son 1

Forms 中没有内置机制,但此 nuget 包提供了类似的功能

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

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

  • Android Toast 的含义完全不同——它是一条弹出消息。该库用于系统范围的通知。 (5认同)