在我们的Xamarin移动应用程序中,我需要显示一个基于计时器的弹出对话框。基本上,如果用户没有单击“确定”按钮,则对话框仍应在十秒钟内消失。
在网上,有人提到为Android和iOS创建自定义对话框。但是,我没有找到任何关于创建跨平台对话框的参考。
似乎有第三方nuget包创建弹出对话框 - http://www.sparkhound.com/learn/blog/creating-a-modal-popup-dialog-in-xamarin-forms,但是,我不想使用第三方软件包。另外,我不知道该库是否支持基于计时器的对话框。
有没有办法创建一个简单的跨平台对话框?从使用角度来看,这是我想的原型:
static void DisplayAlert(string title, string body, int msec);
答案 0 :(得分:2)
这是我在Xamarin.Forms中创建的自定义弹出窗口。它包括一些奇特的动画,甚至模糊背景。我已经在我构建的几个应用程序中成功使用了它。
您可以通过调用ShowView
来触发此自定义弹出窗口。它有一个计时器,将在10秒内解散,或者你可以通过拨打HideView
来解雇它。
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace MyNamespace
{
public abstract class OverlayContentView : ContentView
{
#region Constant Fields
readonly BoxView _backgroundOverlayBoxView;
readonly Frame _overlayFrame;
readonly RelativeLayout _relativeLayout;
#endregion
#region Fields
View _overlayContent;
#endregion
#region Constructors
protected OverlayContentView(bool isChildOfNavigationPage)
{
_backgroundOverlayBoxView = new BoxView
{
BackgroundColor = ColorConstants.WhiteWith75Opacity
};
_backgroundOverlayBoxView.Opacity = 0;
_overlayFrame = new Frame
{
HasShadow = true,
BackgroundColor = Color.White
};
_overlayFrame.Scale = 0;
_relativeLayout = new RelativeLayout();
Func<RelativeLayout, double> getOverlayContentHeight = (p) => OverlayContent.Measure(p.Width, p.Height).Request.Height;
Func<RelativeLayout, double> getOverlayContentWidth = (p) => OverlayContent.Measure(p.Width, p.Height).Request.Width;
_relativeLayout.Children.Add(_backgroundOverlayBoxView,
Constraint.Constant(-10),
Constraint.Constant(0),
Constraint.RelativeToParent(parent => parent.Width + 20),
Constraint.RelativeToParent(parent => parent.Height)
);
_relativeLayout.Children.Add(_overlayFrame,
Constraint.RelativeToParent(parent => parent.Width / 2 - getOverlayContentWidth(parent) / 2 - 25),
Constraint.RelativeToParent(parent =>
{
switch (isChildOfNavigationPage)
{
case true:
return parent.Height / 4 - getOverlayContentHeight(parent) / 2;
default:
return parent.Height / 2 - getOverlayContentHeight(parent) / 2 - 10;
}
}),
Constraint.RelativeToParent(parent => getOverlayContentWidth(parent) + 50),
Constraint.RelativeToParent(parent => getOverlayContentHeight(parent) + 40)
);
}
#endregion
#region Properties
public View OverlayContent
{
get => _overlayContent;
set
{
_overlayContent = value;
_overlayContent.Scale = 0;
_overlayFrame.Content = _overlayContent;
Content = _relativeLayout;
}
}
#endregion
#region Methods
public void ShowView(bool shouldDisappearAfterTimeoutExpires = false, int timeoutInSeconds = 10)
{
const uint overlayContentViewAnimationTime = 300;
const double overlayContentViewMaxSize = 1.05;
const double overlayContentViewNormalSize = 1;
Device.BeginInvokeOnMainThread(async () =>
{
IsVisible = true;
_backgroundOverlayBoxView.Opacity = 1;
await Task.WhenAll(OverlayContent?.ScaleTo(overlayContentViewMaxSize, overlayContentViewAnimationTime, Easing.CubicOut),
_overlayFrame?.ScaleTo(overlayContentViewMaxSize, overlayContentViewAnimationTime, Easing.CubicOut));
await Task.WhenAll(OverlayContent?.ScaleTo(overlayContentViewNormalSize, overlayContentViewAnimationTime, Easing.CubicOut),
_overlayFrame?.ScaleTo(overlayContentViewNormalSize, overlayContentViewAnimationTime, Easing.CubicOut));
if (!shouldDisappearAfterTimeoutExpires)
return;
await Task.Delay(TimeSpan.FromSeconds(timeoutInSeconds));
HideView();
});
}
public void HideView()
{
Device.BeginInvokeOnMainThread(async () =>
{
await this.FadeTo(0);
IsVisible = false;
InputTransparent = true;
Opacity = 1;
_backgroundOverlayBoxView.Opacity = 0;
OverlayContent.Scale = 0;
_overlayFrame.Scale = 0;
});
}
#endregion
}
}
using Xamarin.Forms;
namespace MyNamespace
{
public class WelcomeView : OverlayContentView
{
public WelcomeView() : base(true)
{
const string titleText = "Welcome";
const string bodyText = "Enjoy InvestmentDataSampleApp";
const string okButtonText = "Ok, thanks!";
var titleLabel = new Label
{
FontAttributes = FontAttributes.Bold,
Text = titleText,
HorizontalTextAlignment = TextAlignment.Center
};
var bodyLabel = new Label
{
Text = bodyText,
HorizontalTextAlignment = TextAlignment.Center
};
var okButton = new Button
{
TextColor = Color.White,
FontAttributes = FontAttributes.Bold,
Margin = new Thickness(5),
Text = okButtonText,
BackgroundColor = new Color(0, 0, 0, 0.75),
TextColor = Color.White,
BorderWidthProperty = 1,
BorderColor = new Color(0, 0, 0, 0.75),
};
okButton.Clicked += (sender, e) => this.HideView();
var textAndButtonStack = new StackLayout
{
HorizontalOptions = LayoutOptions.CenterAndExpand,
Spacing = 20,
Children = {
titleLabel,
bodyLabel,
okButton
}
};
OverlayContent = textAndButtonStack;
}
}
}
作为参考,这是一个已实现自定义弹出窗口的示例应用程序: https://github.com/brminnick/InvestmentDataSampleApp
答案 1 :(得分:0)
我建议您看一下这篇文章,我在一段时间前回答:Display a popup with xamarin forms
即使这样的系统需要花费一些时间来实现,它也使您可以从应用程序中的任何位置调用任何对话框,而无需将对话框嵌入内容页面中。
如果您想让对话框计时,可以简单地用
进行调用Dialogs.ShowLoading();
Xamarin.Forms.Device.StartTimer(TimeSpan.FromSeconds(5), () => { Dialogs.Hide();
return false;
});