diff --git a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs index 1984c97d1636..4d1af1801f8a 100644 --- a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs +++ b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs @@ -305,11 +305,34 @@ public override AView OnCreateView(LayoutInflater inflater, ViewGroup? container _navigationRootManager = modalContext.GetNavigationRootManager(); _navigationRootManager.Connect(_modal, modalContext); - + UpdateBackgroundColor(); - return _navigationRootManager?.RootView ?? + var rootView = _navigationRootManager?.RootView ?? throw new InvalidOperationException("Root view not initialized"); + + if (IsAnimated) + { + _ = new GenericGlobalLayoutListener((listener,view) => + { + listener.Invalidate(); + if(view is not null) + { + var animation = AnimationUtils.LoadAnimation(view.Context, Resource.Animation.nav_modal_default_enter_anim)!; + view.StartAnimation(animation); + animation.AnimationEnd += OnAnimationEnded; + } + },_navigationRootManager.RootView); + } + return rootView; + } + void OnAnimationEnded(object? sender, AAnimation.AnimationEndEventArgs e) + { + if (sender is not AAnimation animation) + return; + + animation.AnimationEnd -= OnAnimationEnded; + FireAnimationEnded(); } public override void OnCreate(Bundle? savedInstanceState) @@ -329,26 +352,7 @@ public override void OnStart() int width = ViewGroup.LayoutParams.MatchParent; int height = ViewGroup.LayoutParams.MatchParent; - dialog.Window.SetLayout(width, height); - - if (IsAnimated) - { - var animation = AnimationUtils.LoadAnimation(_mauiWindowContext.Context, Resource.Animation.nav_modal_default_enter_anim)!; - View.StartAnimation(animation); - - animation.AnimationEnd += OnAnimationEnded; - } - - void OnAnimationEnded(object? sender, AAnimation.AnimationEndEventArgs e) - { - if (sender is not AAnimation animation) - { - return; - } - - animation.AnimationEnd -= OnAnimationEnded; - FireAnimationEnded(); - } + dialog.Window.SetLayout(width, height); } public override void OnDismiss(IDialogInterface dialog) diff --git a/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.cs b/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.cs index 65da860603ac..b9650ce6b4e8 100644 --- a/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.cs @@ -578,6 +578,36 @@ await CreateHandlerAndAddToWindow(window, async handler => } #endif + [Fact("Dont leak with Animation")] + public async Task ModalPageDontLeakWithAnimation() + { + SetupBuilder(); + var references = new List(); + + + var page = new ContentPage(); + var window = new Window(page); + + await CreateHandlerAndAddToWindow(window, async handler => + { + var modalPage = new ContentPage + { + Content = new Label { Text = "Modal Content" } + }; + await page.Navigation.PushModalAsync(modalPage,true); + await OnLoadedAsync(modalPage); + + references.Add(new WeakReference(modalPage)); + references.Add(new WeakReference(modalPage.Handler)); + references.Add(new WeakReference(modalPage.Handler.PlatformView)); + + await page.Navigation.PopModalAsync(); + await OnUnloadedAsync(modalPage); + }); + + await AssertionExtensions.WaitForGC(references.ToArray()); + } + class PageTypes : IEnumerable { public IEnumerator GetEnumerator()