Skip to content

Commit 2b2b6d0

Browse files
[Android] Fix: Modal Animation Repeats When Returning from Background 3 (#29702)
* fix * dispose listner once not needed * Revert "dispose listner once not needed" * call invalidate * add device test to check for leaks * null check and remove strong references in callback * Throw if rootview is null before adding animation * fix spelling mistake
1 parent 4b537ae commit 2b2b6d0

File tree

2 files changed

+56
-22
lines changed

2 files changed

+56
-22
lines changed

src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,34 @@ public override AView OnCreateView(LayoutInflater inflater, ViewGroup? container
305305

306306
_navigationRootManager = modalContext.GetNavigationRootManager();
307307
_navigationRootManager.Connect(_modal, modalContext);
308-
308+
309309
UpdateBackgroundColor();
310310

311-
return _navigationRootManager?.RootView ??
311+
var rootView = _navigationRootManager?.RootView ??
312312
throw new InvalidOperationException("Root view not initialized");
313+
314+
if (IsAnimated)
315+
{
316+
_ = new GenericGlobalLayoutListener((listener,view) =>
317+
{
318+
listener.Invalidate();
319+
if(view is not null)
320+
{
321+
var animation = AnimationUtils.LoadAnimation(view.Context, Resource.Animation.nav_modal_default_enter_anim)!;
322+
view.StartAnimation(animation);
323+
animation.AnimationEnd += OnAnimationEnded;
324+
}
325+
},_navigationRootManager.RootView);
326+
}
327+
return rootView;
328+
}
329+
void OnAnimationEnded(object? sender, AAnimation.AnimationEndEventArgs e)
330+
{
331+
if (sender is not AAnimation animation)
332+
return;
333+
334+
animation.AnimationEnd -= OnAnimationEnded;
335+
FireAnimationEnded();
313336
}
314337

315338
public override void OnCreate(Bundle? savedInstanceState)
@@ -329,26 +352,7 @@ public override void OnStart()
329352

330353
int width = ViewGroup.LayoutParams.MatchParent;
331354
int height = ViewGroup.LayoutParams.MatchParent;
332-
dialog.Window.SetLayout(width, height);
333-
334-
if (IsAnimated)
335-
{
336-
var animation = AnimationUtils.LoadAnimation(_mauiWindowContext.Context, Resource.Animation.nav_modal_default_enter_anim)!;
337-
View.StartAnimation(animation);
338-
339-
animation.AnimationEnd += OnAnimationEnded;
340-
}
341-
342-
void OnAnimationEnded(object? sender, AAnimation.AnimationEndEventArgs e)
343-
{
344-
if (sender is not AAnimation animation)
345-
{
346-
return;
347-
}
348-
349-
animation.AnimationEnd -= OnAnimationEnded;
350-
FireAnimationEnded();
351-
}
355+
dialog.Window.SetLayout(width, height);
352356
}
353357

354358
public override void OnDismiss(IDialogInterface dialog)

src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,36 @@ await CreateHandlerAndAddToWindow<IWindowHandler>(window, async handler =>
578578
}
579579
#endif
580580

581+
[Fact("Dont leak with Animation")]
582+
public async Task ModalPageDontLeakWithAnimation()
583+
{
584+
SetupBuilder();
585+
var references = new List<WeakReference>();
586+
587+
588+
var page = new ContentPage();
589+
var window = new Window(page);
590+
591+
await CreateHandlerAndAddToWindow<WindowHandlerStub>(window, async handler =>
592+
{
593+
var modalPage = new ContentPage
594+
{
595+
Content = new Label { Text = "Modal Content" }
596+
};
597+
await page.Navigation.PushModalAsync(modalPage,true);
598+
await OnLoadedAsync(modalPage);
599+
600+
references.Add(new WeakReference(modalPage));
601+
references.Add(new WeakReference(modalPage.Handler));
602+
references.Add(new WeakReference(modalPage.Handler.PlatformView));
603+
604+
await page.Navigation.PopModalAsync();
605+
await OnUnloadedAsync(modalPage);
606+
});
607+
608+
await AssertionExtensions.WaitForGC(references.ToArray());
609+
}
610+
581611
class PageTypes : IEnumerable<object[]>
582612
{
583613
public IEnumerator<object[]> GetEnumerator()

0 commit comments

Comments
 (0)