所以,我正在开发一个Xamarin项目。我正在开发一个应用程序,它将应用程序中有用的弹出窗口发送给用户(例如提示)。用户可以设置他们在应用程序中接收此弹出窗口的时间(例如,他们可以在19:00或12:00接收弹出窗口)。我为这个名为Alert的人创建了一个自定义类。应用程序的IOS版本正在按预期工作
然而,由于股票Android警报没有任何方法可以在其中添加输入字段,我必须为此警报创建一个特殊视图。我现在遇到的主要问题是来自自定义视图的用户输入未发送到Xamarin表单警报。
Android代码:
public class Alert : IAlert
{
public static readonly int AlertWidth = Device.Idiom == TargetIdiom.Phone ? 270 : 320;
class AlertDialogFragment : DialogFragment
{
public string Title;
public string Body;
public View Content;
public List<AlertButton> Buttons;
public Func<Task> tcs;
public Dialog AndroidCustomAlert(Activity activ)
{
Android.Views.LayoutInflater inflater = Android.Views.LayoutInflater.From(activ);
Android.Views.View view = inflater.Inflate(Resource.Layout.AlertDialogLayout, null);
AlertDialog.Builder builder = new AlertDialog.Builder(activ);
builder.SetView(view);
Android.Widget.TextView title = view.FindViewById<Android.Widget.TextView>(Resource.Id.Login);
title.Text = Title;
Android.Widget.TextView body = view.FindViewById<Android.Widget.TextView>(Resource.Id.pincodeText);
body.Text = Body;
Android.Widget.Timepicker timepicker= view.FindViewById<Android.Widget.Timepicker >(Resource.Id.timepicker);
Android.Widget.Button btnPositive = view.FindViewById<Android.Widget.Button>(Resource.Id.btnLoginLL);
Android.Widget.Button btnNegative = view.FindViewById<Android.Widget.Button>(Resource.Id.btnClearLL);
Android.Widget.Button btnNeutral = view.FindViewById<Android.Widget.Button>(Resource.Id.btnNeutral);
//Checks if there are no buttons, and if there aren't any, creates a neutral one
if (Buttons == null || Buttons.Count == 0)
{
btnPositive.Visibility = Android.Views.ViewStates.Gone;
btnNegative.Visibility = Android.Views.ViewStates.Gone;
btnNeutral.Visibility = Android.Views.ViewStates.Visible;
timepicker.Visibility = Android.Views.ViewStates.Gone;
Buttons = new List<AlertButton> {
new AlertButton {
Text = "Oké",
IsPreferred = true,
Action = () => false
}
};
btnNeutral.Text = Buttons.First().Text;
btnNeutral.Click += delegate
{
CommandsForButtons(Buttons.First());
};
}
//Positive button feedback
btnPositive.Text = Buttons.Last().Text;
btnPositive.Click += delegate
{
CommandsForButtons(Buttons.Last());
};
//Negative button feedback
btnNegative.Text = Buttons.First().Text;
btnNegative.Click += delegate
{
CommandsForButtons(Buttons.First());
};
builder.SetCancelable(false);
return builder.Create();
}
public void CommandsForButtons(AlertButton button)
{
var command = new Command(async () =>
{
var ab = button;
var cont = true;
if (ab.Action != null)
cont = ab.Action();
if (ab.ActionAsync != null)
{
cont = cont && await ab.ActionAsync();
}
if (!cont)
{
Dismiss();
}
});
command.Execute(this);
}
public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
var test = AndroidCustomAlert(Activity);
//test.SetCanceledOnTouchOutside(false);
return test;
}
}
public async Task Show(string title, string body, View content, List<AlertButton> buttons)
{
var tcs = new TaskCompletionSource<object>();
var adf = new AlertDialogFragment
{
Title = title,
Body = body,
Content = content,
Buttons = buttons
};
var FragmentManager = ((Activity)Forms.Context).FragmentManager;
FragmentTransaction ft = FragmentManager.BeginTransaction();
//Remove fragment else it will crash as it is already added to backstack
Fragment prev = FragmentManager.FindFragmentByTag("alert");
if (prev != null)
{
ft.Remove(prev);
}
ft.AddToBackStack(null);
adf.Show(ft, "alert");
//await tcs.Task;
return;
}
}
警报类:
public interface IAlert
{
Task Show(string title, string body, View content, List<AlertButton> buttons);
}
public static class Alert
{
public static async Task Show(string title, string body, View content = null, params AlertButton[] buttons)
{
var enabled = MainApp.BackEnabled;
MainApp.BackEnabled = false;
await DependencyService.Get<IAlert>().Show(title, body, content, buttons.ToList());
MainApp.BackEnabled = enabled;
}
}
public class AlertButton
{
public string Text { get; set; }
public bool IsDestructive { get; set; }
public bool IsPreferred { get; set; }
public Func<bool> Action { get; set; }
public Func<Task<bool>> ActionAsync { get; set; }
}}
IOS代码:
public class iOSAlert : IAlert
{
public static readonly int AlertWidth = Device.Idiom == TargetIdiom.Phone ? 270 : 320;
public async Task Show(string title, string body, View content, List<AlertButton> buttons)
{
if (buttons == null || buttons.Count == 0)
{
buttons = new List<AlertButton> {
new AlertButton {
Text = "Oké",
IsPreferred = true,
Action = () => false
}
};
}
Func<Task> dismiss = null;
var captionSize = (double)StyleKit.PhoneDarkLabelStyles.Caption.Setters.First(s => s.Property == Label.FontSizeProperty).Value;
var titleSize = (double)StyleKit.PhoneDarkLabelStyles.Title.Setters.First(s => s.Property == Label.FontSizeProperty).Value;
var top = new StackLayout {
Padding = new Thickness(15, 20, 15, 20),
Spacing = 3,
Children = {
new Label {
Text = title,
Style = StyleKit.PhoneDarkLabelStyles.Title,
FontSize = Math.Max(16, titleSize),
HorizontalTextAlignment = TextAlignment.Center
},
new Label {
Text = body,
Style = StyleKit.PhoneDarkLabelStyles.Body,
//FontSize = ,
FontSize = Math.Max(14, captionSize),
HorizontalTextAlignment = TextAlignment.Center
} ,
new ContentView {
Padding = new Thickness(0,5,0,-10),
VerticalOptions = LayoutOptions.EndAndExpand,
Content = content
}
}
};
var buttonViews = buttons.Select(ab => new Button {
FontSize = Math.Max(16, titleSize),
Text = ab.Text,
FontAttributes = ab.IsPreferred ? FontAttributes.Bold : FontAttributes.None,
TextColor = ab.IsDestructive ? Color.Red : Color.Default,
Command = new Command(async () => {
var cont = true;
if (ab.Action != null)
cont = ab.Action();
if (ab.ActionAsync != null)
cont = cont && await ab.ActionAsync();
if (!cont)
await dismiss();
})
}).ToList();
var grid = new Grid {
RowDefinitions = {
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto }
},
ColumnSpacing = 0,
RowSpacing = 0
};
buttons.ForEach(button => {
grid.ColumnDefinitions.Add(
new ColumnDefinition {
Width = AlertWidth / buttonViews.Count
}
);
});
for (int i = 0; i < buttonViews.Count; i++)
{
grid.Children.Add(new BorderView {
BorderColor = Color.FromRgba(0,0,0,0.2),
Thickness = new Thickness(0, 1, (i + 1 < buttonViews.Count) ? 1 : 0, 0)
}, i, 1);
grid.Children.Add(buttonViews[i], i, 1);
}
grid.Children.Add(top, 0, buttons.Count, 0, 1);
var box = new Frame {
WidthRequest = AlertWidth,
BackgroundColor = Color.FromRgba(1,1,1,0.96),
Padding = 0,
Content = grid
};
var outer = new AbsoluteLayout {
BackgroundColor = Color.FromRgba(0,0,0,0.65),
Opacity = 0,
Children = { box }
};
AbsoluteLayout.SetLayoutFlags(box, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(box,
new Rectangle(0.5, 0.5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
var page = new ContentPage {
Content = /* new ScrollView { Content = */ outer // }
};
var tcs = new TaskCompletionSource<object>();
var topVC = UIApplication.SharedApplication.KeyWindow.RootViewController;
while (topVC.PresentedViewController != null) {
topVC = topVC.PresentedViewController;
}
var vc = page.CreateViewController();
topVC.Add(vc.View);
var innerView = vc.View.Subviews[0].Subviews[0];
vc.View.RemoveFromSuperview();
dismiss = async () => {
dismiss = async () => {};
await outer.FadeTo(0, 50);
innerView.RemoveFromSuperview();
tcs.SetResult(null);
};
topVC.Add(innerView);
await outer.FadeTo(1, 100);
await tcs.Task;
}
}
带条目的警报示例:
await Alert.Show(
"Time" + (isEdit ? "Edit" : "toevoegen"),
"Fill the time in you want to receive an notification.",
tp,
cancelButton,
new AlertButton
{
Text = "Save",
IsPreferred = true,
Action = () =>
{
var newTime = tp.Time.MinutesOnly();
if (!isEdit || newTime != time)
{
if (isEdit) scheduler.RemoveTime(time);
scheduler.AddTime(newTime);
}
return false;
}
}
);
我有以下问题: 如何将用户信息发送到Xamarin Forms警报,而不更改警报类?
亲切的问候,
弗雷德里克
答案 0 :(得分:0)
从您的代码中,您可以使用 任务显示(字符串标题,字符串正文,查看内容,列表按钮); 要获得结果,在Android项目中,您可以使用TaskCompletionSource来等待用户输入。 https://msdn.microsoft.com/en-us/library/dd449174(v=vs.110).aspx
否则,您可以使用acr.userdialogs.prompt执行相同的操作。 https://github.com/aritchie/userdialogs/blob/master/docs/prompt.md