Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions src/Core/src/Handlers/FlyoutView/FlyoutViewHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,6 @@ void UpdateDetail()
void UpdateFlyout()
{
_ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class.");

// Once this issue has been taken care of
// https://github.com/dotnet/maui/issues/8456
// we can remove this code
if (VirtualView.Flyout.Handler?.MauiContext != null &&
VirtualView.Flyout.Handler.MauiContext != MauiContext)
{
VirtualView.Flyout.Handler.DisconnectHandler();
}

_ = VirtualView.Flyout.ToPlatform(MauiContext);

var newFlyoutView = VirtualView.Flyout.ToPlatform();
Expand Down
10 changes: 9 additions & 1 deletion src/Core/src/Handlers/FlyoutView/FlyoutViewHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,19 @@ namespace Microsoft.Maui.Handlers
{
public partial class FlyoutViewHandler : IFlyoutViewHandler
{
public static IPropertyMapper<IFlyoutView, IFlyoutViewHandler> Mapper = new PropertyMapper<IFlyoutView, IFlyoutViewHandler>(ViewHandler.ViewMapper)
// Like IViewHandler.ContainerView, those properties should be set with priority because other mappers depend on them (like IToolbarElement.Toolbar).
// So we have a separate mapper for them.
private static readonly IPropertyMapper<IFlyoutView, IFlyoutViewHandler> FlyoutLayoutMapper = new PropertyMapper<IFlyoutView, IFlyoutViewHandler>()
{
#if ANDROID || WINDOWS || TIZEN
[nameof(IFlyoutView.Flyout)] = MapFlyout,
[nameof(IFlyoutView.Detail)] = MapDetail,
#endif
};

public static IPropertyMapper<IFlyoutView, IFlyoutViewHandler> Mapper = new PropertyMapper<IFlyoutView, IFlyoutViewHandler>(ViewHandler.ViewMapper, FlyoutLayoutMapper)
{
#if ANDROID || WINDOWS || TIZEN
[nameof(IFlyoutView.IsPresented)] = MapIsPresented,
[nameof(IFlyoutView.FlyoutBehavior)] = MapFlyoutBehavior,
[nameof(IFlyoutView.FlyoutWidth)] = MapFlyoutWidth,
Expand Down
50 changes: 34 additions & 16 deletions src/Core/src/Handlers/View/AndroidBatchPropertyMapper.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using System;
using System;
using System.Collections.Generic;

namespace Microsoft.Maui.Handlers
{
#if ANDROID
class AndroidBatchPropertyMapper<TVirtualView, TViewHandler> : PropertyMapper<TVirtualView, TViewHandler>
where TVirtualView : IElement
where TViewHandler : IElementHandler
class AndroidBatchPropertyMapper
{
public const string InitializeBatchedPropertiesKey = "_InitializeBatchedProperties";

// During mass property updates, this list of properties will be skipped
public static HashSet<string> SkipList = new(StringComparer.Ordinal)
{
Expand All @@ -27,30 +27,48 @@ class AndroidBatchPropertyMapper<TVirtualView, TViewHandler> : PropertyMapper<TV
nameof(IView.AnchorX),
nameof(IView.AnchorY),
};
}

class AndroidBatchPropertyMapper<TVirtualView, TViewHandler> : PropertyMapper<TVirtualView, TViewHandler>
where TVirtualView : IElement
where TViewHandler : IElementHandler
{

public AndroidBatchPropertyMapper(params IPropertyMapper[] chained) : base(chained) { }

public override IEnumerable<string> GetKeys()
{
foreach (var key in _mapper.Keys)
var skipList = AndroidBatchPropertyMapper.SkipList;

// We want to retain the initial order of the keys to avoid race conditions
// when a property mapping is overridden by a new instance of property mapper.
// As an example, the container view mapper should always run first.
// Siblings mapper should not have keys intersection.
var chainedPropertyMappers = Chained;
if (chainedPropertyMappers is not null)
{
// When reporting the key list for mass updates up the chain, ignore properties in SkipList.
// These will be handled by ViewHandler.SetVirtualView() instead.
if (SkipList.Contains(key))
for (int i = chainedPropertyMappers.Length - 1; i >= 0; i--)
{
continue;
foreach (var key in chainedPropertyMappers[i].GetKeys())
{
yield return key;
}
}

yield return key;
}

if (Chained is not null)
// Enqueue keys from this mapper.
foreach (var mapper in _mapper)
{
foreach (var chain in Chained)
foreach (var key in chain.GetKeys())
yield return key;
var key = mapper.Key;

// When reporting the key list for mass updates up the chain, ignore properties in SkipList.
// These will be handled by ViewHandler.SetVirtualView() instead.
if (!skipList.Contains(key))
{
yield return key;
}
}
}
}
#endif
}
}
13 changes: 7 additions & 6 deletions src/Core/src/Handlers/View/ViewHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,17 @@ public abstract partial class ViewHandler : ElementHandler, IViewHandler
public static IPropertyMapper<IView, IViewHandler> ViewMapper =
#if ANDROID
// Use a custom mapper for Android which knows how to batch the initial property sets
new AndroidBatchPropertyMapper<IView, IViewHandler>(ElementMapper)
new AndroidBatchPropertyMapper<IView, IViewHandler>(ElementHandler.ElementMapper)
#else
new PropertyMapper<IView, IViewHandler>(ElementHandler.ElementMapper)
#endif
{
// This property is a special one and needs to be set before other properties.
[nameof(IViewHandler.ContainerView)] = MapContainerView,
#if ANDROID
[AndroidBatchPropertyMapper.InitializeBatchedPropertiesKey] = MapInitializeBatchedProperties,
#endif

[nameof(IView.AutomationId)] = MapAutomationId,
[nameof(IView.Clip)] = MapClip,
[nameof(IView.Shadow)] = MapShadow,
Expand All @@ -56,7 +62,6 @@ public abstract partial class ViewHandler : ElementHandler, IViewHandler
[nameof(IView.RotationY)] = MapRotationY,
[nameof(IView.AnchorX)] = MapAnchorX,
[nameof(IView.AnchorY)] = MapAnchorY,
[nameof(IViewHandler.ContainerView)] = MapContainerView,
#pragma warning disable CS0618 // Type or member is obsolete
[nameof(IBorder.Border)] = MapBorderView,
#pragma warning restore CS0618 // Type or member is obsolete
Expand All @@ -68,10 +73,6 @@ public abstract partial class ViewHandler : ElementHandler, IViewHandler
#if WINDOWS || MACCATALYST
[nameof(IContextFlyoutElement.ContextFlyout)] = MapContextFlyout,
#endif

#if ANDROID
["_InitializeBatchedProperties"] = MapInitializeBatchedProperties
#endif
};

/// <summary>
Expand Down
5 changes: 4 additions & 1 deletion src/Core/src/Platform/iOS/ContainerViewController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ public override void LoadView()

void LoadPlatformView(IElement view)
{
currentPlatformView = _pendingLoadedView ?? CreatePlatformView(view);
var platformView = _pendingLoadedView ?? CreatePlatformView(view);
platformView = platformView.Superview as WrapperView ?? platformView;

currentPlatformView = platformView;
_pendingLoadedView = null;

View!.AddSubview(currentPlatformView);
Expand Down
Loading
Loading