[英]Toast equivalent for Xamarin Forms
Is there any way using Xamarin Forms (not Android or iOS specific) to have a pop-up, like Android does with Toast, that needs no user interaction and goes away after a (short) period of time?有没有什么方法可以使用 Xamarin Forms(不是 Android 或 iOS 特定)弹出一个窗口,就像 Android 对 Toast 所做的那样,不需要用户交互并且在(短)时间后消失?
From searching around all I'm seeing are alerts that need user clicks to go away.通过搜索,我看到的是需要用户点击才能消失的警报。
There is a simple solution for this.有一个简单的解决方案。 By using the DependencyService you can easily get the Toast-Like approach in both Android and iOS.
通过使用DependencyService ,您可以轻松地在 Android 和 iOS 中获得 Toast-Like 方法。
Create an interface in your common package.在您的公共包中创建一个接口。
public interface IMessage
{
void LongAlert(string message);
void ShortAlert(string message);
}
Android section安卓版块
[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 section iOS版块
In iOs there is no native solution like Toast, so we need to implement our own approach.在 iOs 中没有像 Toast 这样的原生解决方案,所以我们需要实现自己的方法。
[assembly: Xamarin.Forms.Dependency(typeof(MessageIOS))]
namespace Your.Namespace
{
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.请注意,在每个平台中,我们都必须使用 DependencyService 注册我们的类。
Now you can access out Toast service in anywhere in our project.现在您可以在我们项目的任何地方访问 Toast 服务。
DependencyService.Get<IMessage>().ShortAlert(string message);
DependencyService.Get<IMessage>().LongAlert(string message);
您可以使用来自 nuget 的Acr.UserDialogs包和如下代码,
Acr.UserDialogs.UserDialogs.Instance.Toast(Message, new TimeSpan(3));
Here's a version of Alex Chengalan's iOS code that avoids the UI sticking when multiple messages are shown...这是 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();
}
}
}
You can use SnackBar
from Xamarin Community toolkit package, which uses native implementation in platforms where natively supported, because Toast
is deprecated in API level 30, a SnackBar
without an Action is equivalent to a Toast.您可以使用Xamarin 社区工具包包中的
SnackBar
,它在本机支持的平台中使用本机实现,因为在 API 级别 30 中不推荐使用Toast
,没有 Action 的SnackBar
等效于 Toast。
This method was deprecated in API level 30. Custom toast views are deprecated.
此方法在 API 级别 30 中已弃用。自定义 toast 视图已弃用。 Apps can create a standard text toast with the makeText(android.content.Context, java.lang.CharSequence, int) method, or use a Snackbar when in the foreground.
应用程序可以使用 makeText(android.content.Context, java.lang.CharSequence, int) 方法创建标准文本 toast,或者在前台使用 Snackbar。 Starting from Android Build.VERSION_CODES#R, apps targeting API level Build.VERSION_CODES#R or higher that are in the background will not have custom toast views displayed.
从 Android Build.VERSION_CODES#R 开始,在后台面向 API 级别 Build.VERSION_CODES#R 或更高级别的应用将不会显示自定义 toast 视图。 ( source ).
(来源)。
using Xamarin.CommunityToolkit.Extensions;
using Xamarin.CommunityToolkit.Extensions;
await this.DisplayToastAsync("This is a Toast Message");
await this.DisplayToastAsync("This is a Toast Message for 5 seconds", 5000);
You may specify a duration for the SnackBar to disappear (in milliseconds) or leave the default one which equals 3 seconds.您可以指定 SnackBar 消失的持续时间(以毫秒为单位)或保留等于 3 秒的默认值。
Official Repo https://github.com/xamarin/XamarinCommunityToolkit官方回购https://github.com/xamarin/XamarinCommunityToolkit
Official Docs https://docs.microsoft.com/en-us/xamarin/community-toolkit/官方文档https://docs.microsoft.com/en-us/xamarin/community-toolkit/
DisplayToastAsync()
from that view (anchor) object instead from the page instance ( this
): this
)调用扩展方法DisplayToastAsync()
来将 toast 锚定在视图上方(如上面的屏幕截图):<Button x:name="floatingButton" .../>
await floatingButton.DisplayToastAsync("This is a Toast Message for 5 seconds", 5000);
You can set the corner radius and the padding for your Toast like the following example:您可以为 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);
PS: The same properties could be applied for the SnackBar
view. PS:相同的属性可以应用于
SnackBar
视图。
If what xct SnackBar
offers doesn't fulfil your requirements or you want to display not only text but some complexe view, you might have to use a popup instead.如果 xct
SnackBar
提供的内容不能满足您的要求,或者您不仅想显示文本,还想显示一些复杂的视图,您可能不得不使用弹出窗口。
Adding to Alex's answer, here's the UWP variant:添加到亚历克斯的答案,这是 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();
}
}
Coloring and styling is up to you, the MaxHeight
is actually required to keep the height at the minimum.着色和样式由您决定,实际上需要
MaxHeight
才能将高度保持在最小值。
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 ).我们通常会使用 Egors Toasts 插件,但由于当前项目需要 iOS 上的权限,所以我们使用
Rg.Plugins.Popup
nuget( https://github.com/rotorgames/Rg.Plugins.Popup )走了一条不同的路线)。
I wrote a basic xaml/cs page of type PopupPage,我写了一个 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">
...
and had it created by a service, whose interface you registered at app start or use Xamarin.Forms.DependencyService
to fetch the service would be viable too.并由服务创建,您在应用程序启动时注册其接口或使用
Xamarin.Forms.DependencyService
获取服务也是可行的。
The service news up the PopupPage derived page, and does该服务更新 PopupPage 派生页面,并执行
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 fine on iOS/Droid, but I'm open to correction if anyone knows what this is a risky way of doing it.这似乎在 iOS/Droid 上运行良好,但如果有人知道这是一种冒险的做法,我愿意更正。
You can use IUserDialog NuGet and simply use it's toastAlert您可以使用 IUserDialog NuGet并简单地使用它的 toastAlert
var toastConfig = new ToastConfig("Toasting...");
toastConfig.SetDuration(3000);
toastConfig.SetBackgroundColor(System.Drawing.Color.FromArgb(12, 131, 193));
UserDialogs.Instance.Toast(toastConfig);
Here is a code snippet that I am using to show the toast in Xamarin.iOS这是我用来在 Xamarin.iOS 中显示 toast 的代码片段
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();
}
@MengTim, to fix the multiple toast issue in @alex-chengalan's solution, I simply wrapped everything within ShowAlert()
with a check to see if alert
and alertDelay
are null, then within DismissMessage
, nulled out alert
and alertDelay
. @MengTim,为了解决@alex-chengalan 的解决方案中的多个 toast 问题,我只是将所有内容都包装在
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;
}
}
That seemed to at least clear up the UI hang, if you are looking for a quick fix.如果您正在寻找快速修复,这似乎至少可以清除 UI 挂起。 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.我试图在导航到新页面时显示 toast,并相信设置的
PresentViewController
基本上取消了我的导航。 Sorry I did not comment within the thread, my reputation is too low :(抱歉,我没有在帖子中发表评论,我的声誉太低了:(
I would recommend Plugin.Toast
library from nuget
.我会推荐
Plugin.Toast
的nuget
库。 It works well.它运作良好。
CrossToastPopUp.Current.ShowToastMessage("my toast message");
or from ACR.UserDialogs Nuget libriary或来自 ACR.UserDialogs Nuget 库
UserDialogs.Instance.ShowLoading("Loading");
This is my improved ShowAlert
version of Ian Warburton's version to ensure that the toast is displayed even on popup page.这是我改进的 Ian Warburton 版本的
ShowAlert
版本,以确保即使在弹出页面上也能显示 toast。 Furthermore, the toast is dissmissed if the user click outside the toast.此外,如果用户在 toast 之外单击,则取消 toast。 I used
UIAlertControllerStyle.ActionSheet
that look likes toast but it also work with UIAlertControllerStyle.Alert
我使用
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);
});
}
I hope this will help someone !我希望这会对某人有所帮助!
There is no built-in mechanism in Forms, but this nuget package supplies something similar Forms 中没有内置机制,但是这个 nuget 包提供了类似的东西
https://github.com/EgorBo/Toasts.Forms.Plugin 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.注意:这些不是问题中要求的 Android 风格的祝酒词,而是 UWP 风格的祝酒词,它们是系统范围的通知。
I used https://github.com/ishrakland/Toast/ In https://www.nuget.org/packages/Plugin.Toast/我使用https://github.com/ishrakland/Toast/在https://www.nuget.org/packages/Plugin.Toast/
Example:例子:
CrossToastPopUp.Current.ShowToastMessage ("Loading", Plugin.Toast.Abstractions.ToastLength.Short);
Give it a try.试试看。
I customised a custom popup with Rg.Plugins.Popup NuGet this is an example:我使用 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>
then in your basecontentpage you can add the following code, to show and hide the "toast" after a while:然后在您的 basecontentpage 中,您可以添加以下代码,以在一段时间后显示和隐藏“toast”:
public async void showpopup(string msg)
{
await Navigation.PushPopupAsync(new Toast(msg));
await Task.Delay(3000);
await Navigation.PopPopupAsync(true);
}
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!上面的 iOS 答案对我有用,但有一个小问题——警告:尝试呈现 UIAlertController ...其视图不在窗口层次结构中!
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:所以,我用这些行修改了上面的 ShowAlert() 函数,这似乎有效:
var rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController;
while ( rootVC.PresentedViewController != null) {
rootVC = rootVC.PresentedViewController;
}
rootVC.PresentViewController( alert, true, null);
For UWP对于 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);
}
检查plugin.toast v 2.1.2适用于android,iOS和UWP
Look this. 看看这个。 It work's fine on Android and iOS.
在Android和iOS上都可以正常工作。
https://www.nuget.org/packages/Plugin.Toast/ https://www.nuget.org/packages/Plugin.Toast/
Install nuget Acr.UserDialogs .安装 nuget Acr.UserDialogs 。 It contains Toasts exactly what you are looking for.
它包含您正在寻找的Toasts 。
ToastEvent toastEvent = new ToastEvent();
var toastConfig = new ToastConfig(toastEvent,"Toasting...","");
toastConfig.SetDuration(2000);
UserDialogs.Instance.Toast(toastConfig);
Currently use xamarin essential in android:目前在android中使用xamarin必不可少:
//access mainthread
MainThread.BeginInvokeOnMainThread(() =>
{
Toast.MakeText(Application.Context, message, ToastLength.Short).Show();
});
Adding Alex's code, for UWP variant, I found a great implementation here https://www.c-sharpcorner.com/article/xamarin/添加亚历克斯的代码,对于 UWP 变体,我在这里找到了一个很好的实现https://www.c-sharpcorner.com/article/xamarin/
Just come and leave a clap for him :)过来为他鼓掌吧:)
[assembly:Xamarin.Forms.Dependency(typeof(Toast_UWP))]
namespace ToastMessage.UWP
{
class Toast_UWP : Toast
{
public void Show(string message)
{
ToastTemplateType toastTemplate = ToastTemplateType.ToastImageAndText01;
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);
XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
toastTextElements[0].AppendChild(toastXml.CreateTextNode(message));
XmlNodeList toastImageAttributes = toastXml.GetElementsByTagName("image");
((XmlElement)toastImageAttributes[0]).SetAttribute("src", "ms-appx:///Assets/Logo.scale-240.png");
((XmlElement)toastImageAttributes[0]).SetAttribute("alt", "logo");
IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
((XmlElement)toastNode).SetAttribute("duration", "short");
var toastNavigationUriString = "#/MainPage.xaml?param1=12345";
var toastElement = ((XmlElement)toastXml.SelectSingleNode("/toast"));
toastElement.SetAttribute("launch", toastNavigationUriString);
ToastNotification toast = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
}
}
By default, your messages will be queued and notified one after one, delayed based on the message duration.默认情况下,您的消息将根据消息持续时间进行延迟排队和一条接一条通知。 If you want to replace the existing message by the new one immediately just add more code like below
如果您想立即用新消息替换现有消息,只需添加更多代码,如下所示
ToastNotificationManager.History.Remove("YOUR_TAG");
// Code to create Toast message, like the above method
toast.Tag = "YOUR_TAG";
If you want to add audio to your toast message, add this to your code如果您想在 toast 消息中添加音频,请将其添加到您的代码中
var audio = toastXml.CreateElement("audio");
audio.SetAttribute("src", "ms-winsoundevent:Notification.Default");
You could use the Xamarin.Toolkit and follow this information provided by MS.您可以使用 Xamarin.Toolkit 并遵循 MS 提供的此信息。 https://docs.microsoft.com/en-us/xamarin/community-toolkit/views/popup
https://docs.microsoft.com/en-us/xamarin/community-toolkit/views/popup
In my application I could manage it by putting every code-thing between a viewmodel, the view and a method called DismissThisPopup().在我的应用程序中,我可以通过将每个代码事物放在视图模型、视图和名为 DismissThisPopup() 的方法之间来管理它。 So it is possible to controll it from outside of the current Mainpage.
因此可以从当前主页之外对其进行控制。
To acomplish your request.完成您的请求。 You could call await Task.Delay(5000);
你可以调用 await Task.Delay(5000); //as example 5sec after you called your popup.Open();
//作为示例,在您调用 popup.Open() 后 5 秒; so it might look like:
所以它可能看起来像:
...
var vm = new MyPopUpViewModel()
vm.DisplayText = "this could be your text";
vm.DelayTimeForDismiss = 5000;
vm.IsLightDismissAllowed = false; //used that you can not close the popup by clicking around
await vm.OpenPopupAsync();
then in your vm OpenPopUpAsync()然后在你的虚拟机 OpenPopUpAsync()
...other properties and stuff
internal PopUpLoadingView popup = new PopUpLoadingView();//this is the view created with the informations from MS
public async Task OpenPopUp()
{
popup.BindingContext = this;
Application.Current.MainPage.Navigation.ShowPopup(popup: popup);
await Task.Delay(DelayTimeForDismiss);
popup.DismissThisPopup();
}
and in your PopUpLoadingView, insert this method:并在您的 PopUpLoadingView 中,插入此方法:
...other stuff
public void DismissThisPopup()
{
Dismiss(this);
}
您可以使用DisplayAlert("", "", "", "" );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.