maui-linux/Xamarin.Forms.Platform.Android/PopupManager.cs

167 строки
4.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Android.App;
using Android.Content;
using Xamarin.Forms.Internals;
namespace Xamarin.Forms.Platform.Android
{
internal static class PopupManager
{
static readonly List<PopupRequestHelper> s_subscriptions = new List<PopupRequestHelper>();
internal static void Subscribe(Activity context)
{
if (s_subscriptions.Any(s => s.Activity == context))
{
return;
}
s_subscriptions.Add(new PopupRequestHelper(context));
}
internal static void Unsubscribe(Context context)
{
var toRemove = s_subscriptions.Where(s => s.Activity == context).ToList();
foreach (PopupRequestHelper popupRequestHelper in toRemove)
{
popupRequestHelper.Dispose();
s_subscriptions.Remove(popupRequestHelper);
}
}
internal static void ResetBusyCount(Activity context)
{
s_subscriptions.FirstOrDefault(s => s.Activity == context)?.ResetBusyCount();
}
internal sealed class PopupRequestHelper : IDisposable
{
int _busyCount;
bool? _supportsProgress;
internal PopupRequestHelper(Activity context)
{
Activity = context;
MessagingCenter.Subscribe<Page, bool>(Activity, Page.BusySetSignalName, OnPageBusy);
MessagingCenter.Subscribe<Page, AlertArguments>(Activity, Page.AlertSignalName, OnAlertRequested);
MessagingCenter.Subscribe<Page, ActionSheetArguments>(Activity, Page.ActionSheetSignalName, OnActionSheetRequested);
}
public Activity Activity { get; }
public void Dispose()
{
MessagingCenter.Unsubscribe<Page, AlertArguments>(Activity, Page.AlertSignalName);
MessagingCenter.Unsubscribe<Page, bool>(Activity, Page.BusySetSignalName);
MessagingCenter.Unsubscribe<Page, ActionSheetArguments>(Activity, Page.ActionSheetSignalName);
}
public void ResetBusyCount()
{
_busyCount = 0;
}
void OnPageBusy(Page sender, bool enabled)
{
// Verify that the page making the request is part of this activity
if (!PageIsInThisContext(sender))
{
return;
}
_busyCount = Math.Max(0, enabled ? _busyCount + 1 : _busyCount - 1);
UpdateProgressBarVisibility(_busyCount > 0);
}
void OnActionSheetRequested(Page sender, ActionSheetArguments arguments)
{
// Verify that the page making the request is part of this activity
if (!PageIsInThisContext(sender))
{
return;
}
var builder = new AlertDialog.Builder(Activity);
builder.SetTitle(arguments.Title);
string[] items = arguments.Buttons.ToArray();
builder.SetItems(items, (o, args) => arguments.Result.TrySetResult(items[args.Which]));
if (arguments.Cancel != null)
builder.SetPositiveButton(arguments.Cancel, (o, args) => arguments.Result.TrySetResult(arguments.Cancel));
if (arguments.Destruction != null)
builder.SetNegativeButton(arguments.Destruction, (o, args) => arguments.Result.TrySetResult(arguments.Destruction));
AlertDialog dialog = builder.Create();
builder.Dispose();
//to match current functionality of renderer we set cancelable on outside
//and return null
dialog.SetCanceledOnTouchOutside(true);
dialog.CancelEvent += (o, e) => arguments.SetResult(null);
dialog.Show();
}
void OnAlertRequested(Page sender, AlertArguments arguments)
{
// Verify that the page making the request is part of this activity
if (!PageIsInThisContext(sender))
{
return;
}
AlertDialog alert = new AlertDialog.Builder(Activity).Create();
alert.SetTitle(arguments.Title);
alert.SetMessage(arguments.Message);
if (arguments.Accept != null)
alert.SetButton((int)DialogButtonType.Positive, arguments.Accept, (o, args) => arguments.SetResult(true));
alert.SetButton((int)DialogButtonType.Negative, arguments.Cancel, (o, args) => arguments.SetResult(false));
alert.CancelEvent += (o, args) => { arguments.SetResult(false); };
alert.Show();
}
void UpdateProgressBarVisibility(bool isBusy)
{
if (!SupportsProgress)
return;
#pragma warning disable 612, 618
Activity.SetProgressBarIndeterminate(true);
Activity.SetProgressBarIndeterminateVisibility(isBusy);
#pragma warning restore 612, 618
}
internal bool SupportsProgress
{
get
{
if (_supportsProgress.HasValue)
{
return _supportsProgress.Value;
}
int progressCircularId = Activity.Resources.GetIdentifier("progress_circular", "id", "android");
if (progressCircularId > 0)
_supportsProgress = Activity.FindViewById(progressCircularId) != null;
else
_supportsProgress = true;
return _supportsProgress.Value;
}
}
bool PageIsInThisContext(Page page)
{
var renderer = Platform.GetRenderer(page);
if (renderer?.View?.Context == null)
{
return false;
}
return renderer.View.Context.Equals(Activity);
}
}
}
}