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

167 строки
4.8 KiB
C#
Исходник Обычный вид История

[All] Page embedding (#1124) * Fix broken SetTextAppearance call when targeting below API 23 * Enable embedding XF apps in Android * VS didn't save the project file * Allow retrieving rendered XF VisualElements for use in UWP apps * Prevent XF from slaughtering the menu bar in embedded scenarios * ? * Post-rebase fixups * Create embedding test project for Android * Create iOS test bed project * Attempting to get functional embedded project * Android and iOS functional testbed projects * Basic embedding app on UWP * First pass at handling navigation to Forms page from UWP * Fleshed out example, added parameter checks, sealed wrapper class * Create test page and load it from UWP * Make DisplayAlert/DisplayActionSheet independent of Platform instance on UWP * Set up test page for alerts/actionsheets on Android * Move DisplayAlert/ActionSheet code to a helper class so embedded Forms can use it * VS didn't save my changes * Add test page for alerts and action sheets * Get FrameworkElement from renderer * Page -> ContentPage * Can now display the webview embedded page * Example working on iOS * Repro of crash * Remove the IStartActivityForResult dependency from FormsWebChromeClient * Created repro * Remove need for Forms.Context to create renderers * Remove Forms.Context dependencies in ScrollViewRenderer * Remove Forms.Context dependencies in FrameRenderer * Remove Forms.Context dependencies * Remove Context/Forms.Context dependencies in Drawable subclasses * Remove some more Forms.Context dependencies * CellAdapter no longer dependent on Forms.Context * Obsolete ToAndroid using Forms.Context * Remove Forms.Context dependencies in ResourceManager * Remove need for Forms.Context for SupportsProgress * Remove Forms.Context dependency for setting titlebar visibility * Remove Forms.Context dependencies in GetAccentColor * Some comments about caching * Remove Forms.Context dependencies for AndroidPlatformServices and ResourceProvider * Remove Forms.Context dependencies in Maps * Disabled warnings for Forms.Context in CustomRenderers * Filter logs so we don't get those annoying "parked" messages * Filter alerts/actionsheets/activityindicator by context * Clean up constructor debugging messages * Remove old TODOs * Set up test page for Device.Openuri * Make AndroidDeviceInfo more resilient to multiple activity scenarios * Use parameter instead of member * Add missing parameterless constructors for embedded fragment wrappers * Fix multiple popup subscriptions for embedded context * Remove UpdateGlobalContext and Page Context attached property * Obsolete static reference to Context * Warnings as errors in embedded test bed projects * Comment cleanup * Clean up unused code * Obsolete old constructor for DefaultRenderer * Make sure embedded fragment wrappers handle disposing the platform * Revert to old DependencyService registration for ResourceProvider; use ApplicationContext for ResourceProvider; Comments for everything happing in Forms.SetupInit * Remove old TODO * Make PopupManager take the correct type instead of casting a bunch * Update docs * Add missing nuspec entry for FormsEmbeddedPageWrapper * Post-rebase cleanup * Update docs * Disable XF target validation so package restore works * Restore InputTransparent handling lost in rebase * Restore parameter lost during rebase * Finalize the list of subscriptions to avoid 'modified collection' errors * Avoid double-fetching Context * Fix "with you package" typo
2017-10-09 20:51:55 +03:00
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);
}
}
}
}