Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Xamarin形式的吐司等效物_C#_Xamarin_Xamarin.forms_Toast - Fatal编程技术网

C# Xamarin形式的吐司等效物

C# Xamarin形式的吐司等效物,c#,xamarin,xamarin.forms,toast,C#,Xamarin,Xamarin.forms,Toast,是否有任何方法可以使用Xamarin表单(不是Android或iOS特有的)来创建一个弹出窗口,就像Android在Toast中所做的那样,不需要用户交互,并且在(短)一段时间后就会消失 通过搜索,我看到的都是需要用户点击才能消失的警报。表单中没有内置机制,但这个nuget包提供了类似的功能 注意:这些不是问题中要求的Android风格的祝酒词,而是UWP风格的祝酒词,它们是系统范围内的通知。下面是我用来在Xamarin.iOS中显示祝酒词的代码片段 public void ShowToa

是否有任何方法可以使用Xamarin表单(不是Android或iOS特有的)来创建一个弹出窗口,就像Android在Toast中所做的那样,不需要用户交互,并且在(短)一段时间后就会消失


通过搜索,我看到的都是需要用户点击才能消失的警报。

表单中没有内置机制,但这个nuget包提供了类似的功能


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

下面是我用来在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();
    }

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

在通用软件包中创建一个接口。

public interface IMessage
{
    void LongAlert(string message);
    void ShortAlert(string message);
}
安卓部分

[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部分

[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中没有像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注册我们的类

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

DependencyService.Get<IMessage>().ShortAlert(string message); 
DependencyService.Get<IMessage>().LongAlert(string message);
DependencyService.Get().ShortAlert(字符串消息);
DependencyService.Get().LongAlert(字符串消息);

我们通常会使用Egors Toasts插件,但由于当前项目需要在iOS上的权限,我们使用Rg.Plugins.Popup nuget()采用了不同的方法

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

<?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">
...
用户可以通过点击页面显示的外部来关闭弹出页面(假设它没有填满屏幕)


这似乎在iOS/Droid上运行得很好,但如果有人知道这是一种危险的操作方式,我愿意纠正。

@MengTim,为了解决@alex chengalan解决方案中的多重吐司问题,我只需将所有内容包装在
showarter()
中,检查
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挂起的问题。我试图在导航到新页面时显示toast,并且认为设置的
PresentViewController
实际上取消了我的导航。很抱歉,我没有在帖子中发表评论,我的声誉太低了:(

这里有一个Alex Chengalan的iOS版本,可以避免在显示多条消息时用户界面卡住

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

除了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
实际上需要将高度保持在最小值。

这是我改进的伊恩·沃伯顿版本的
ShowAlert
版本,以确保即使在弹出页面上也能显示烤面包片。 此外,如果用户在toast外部单击,则toast将丢失。 我使用了看起来像toast的
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);
        });
    }

我希望这会对某些人有所帮助!

上面的iOS答案对我来说很有用,但有一个小问题——警告:尝试呈现UIAlertController…其视图不在窗口层次结构中

经过一番搜索,我发现这一点很有帮助。海报上说“这看起来很愚蠢,但很有效”,这两方面都是正确的

因此,我用以下几行代码修改了上面的ShowAlert()函数,它们似乎可以工作:

    var rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController;
    while ( rootVC.PresentedViewController != null) {
        rootVC = rootVC.PresentedViewController;
    }
    rootVC.PresentViewController( alert, true, null);
您可以使用IUserDialog并简单地使用它的ToAstateRT

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

UserDialogs.Instance.Toast(toastConfig);
用于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);
    }

您可以使用nuget提供的Acr.UserDialogs包,代码如下:

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

您可以使用
DisplayAlert(“,”,“,”,”,”);

我建议使用
Plugin.Toast
库(来自
nuget
),它工作得很好

CrossToastPopUp.Current.ShowToastMessage("my toast message");
或者从ACR.UserDialogs Nuget libriary

UserDialogs.Instance.ShowLoading("Loading");
我用 在里面

范例 CrossToastOpup.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>

您可以从软件包中使用
SnackBar
,该软件包在本机支持的平台中使用本机实现,因为
Toast
在API级别30中被弃用,没有动作的
SnackBar
相当于Toast

此方法在API级别30中被弃用。 不推荐使用自定义toast视图。应用程序可以使用makeText(android.content.Context、java.lang.CharSequence、int)创建标准文本toast方法,或在前台使用Snackbar。从Android Build开始。版本代码R,面向API级别构建的应用程序。背景中的版本代码R或更高版本不会显示自定义toast视图。()

  • 在所有项目上安装该软件包
  • 使用Xamarin.CommunityToolkit.Extensions包含命名空间
  • 在您的页面中,代码隐藏在事件后显示一个SnackBar
  • 您可以指定SnackBar消失的持续时间(以毫秒为单位),或保留默认值,即3秒


    资源 正式回购


    官方文档安装nugetAcr.UserDialogs。 它包含了你想要的祝酒词

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

    目前在android中使用xamarin essential:

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

    这是到目前为止这个问题的最佳答案。不需要第三方插件或库。在DependencyService行中,我得到“对象引用未设置为对象的实例”是的,这是到目前为止最好的答案,我喜欢充满win的依赖服务。你会碰巧有UWP版本吗?@MengTim我似乎已经通过每次创建一个新的警报和计时器修复了卡住的UI。两者都需要传递到
    DismissMessage
    。Android Toast意味着完全不同的事情-它是一个弹出消息。这是库用于系统范围的通知。应具有r
    ToastEvent toastEvent = new ToastEvent();
    var toastConfig = new ToastConfig(toastEvent,"Toasting...","");
    toastConfig.SetDuration(2000);
    
    UserDialogs.Instance.Toast(toastConfig);
    
    //access mainthread
    MainThread.BeginInvokeOnMainThread(() =>
    {
         Toast.MakeText(Application.Context, message, ToastLength.Short).Show();       
    });