Skip to content

Commit fc140f3

Browse files
kubafloPureWeen
authored andcommitted
[Android] ModalNavigationManager
1 parent 4763a0f commit fc140f3

File tree

3 files changed

+66
-6
lines changed

3 files changed

+66
-6
lines changed

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ async Task PresentModal(Page modal, bool animated)
197197
var dialogFragment = new ModalFragment(WindowMauiContext, modal)
198198
{
199199
Cancelable = false,
200-
IsAnimated = animated
200+
IsAnimated = animated,
201+
modalNavigationManager = this
201202
};
202203

203204
var fragmentManager = WindowMauiContext.GetFragmentManager();
@@ -236,6 +237,7 @@ internal class ModalFragment : DialogFragment
236237

237238
public event EventHandler? AnimationEnded;
238239

240+
public ModalNavigationManager? modalNavigationManager { get; internal set; }
239241

240242
public bool IsAnimated { get; internal set; }
241243

@@ -249,7 +251,7 @@ public ModalFragment(IMauiContext mauiContext, Page modal)
249251

250252
public override global::Android.App.Dialog OnCreateDialog(Bundle? savedInstanceState)
251253
{
252-
var dialog = new CustomComponentDialog(RequireContext(), Theme);
254+
var dialog = new CustomComponentDialog(RequireContext(), Theme, modalNavigationManager);
253255

254256
if (dialog is null || dialog.Window is null)
255257
throw new InvalidOperationException($"{dialog} or {dialog?.Window} is null, and it's invalid");
@@ -404,18 +406,21 @@ void FireAnimationEnded()
404406

405407
sealed class CustomComponentDialog : ComponentDialog
406408
{
407-
public CustomComponentDialog(Context context, int themeResId) : base(context, themeResId)
409+
public CustomComponentDialog(Context context, int themeResId, ModalNavigationManager? modalNavigationManager) : base(context, themeResId)
408410
{
409-
this.OnBackPressedDispatcher.AddCallback(new CallBack(true, this));
411+
this.OnBackPressedDispatcher.AddCallback(new CallBack(true, this, modalNavigationManager));
410412
}
411413

412414
sealed class CallBack : OnBackPressedCallback
413415
{
414416
WeakReference<CustomComponentDialog> _customComponentDialog;
415417

416-
public CallBack(bool enabled, CustomComponentDialog customComponentDialog) : base(enabled)
418+
private ModalNavigationManager? _modalNavigationManager;
419+
420+
public CallBack(bool enabled, CustomComponentDialog customComponentDialog, ModalNavigationManager? modalNavigationManager) : base(enabled)
417421
{
418422
_customComponentDialog = new(customComponentDialog);
423+
_modalNavigationManager = modalNavigationManager;
419424
}
420425

421426
public override void HandleOnBackPressed()
@@ -453,7 +458,7 @@ public override void HandleOnBackPressed()
453458

454459
if (!preventBackPropagation)
455460
{
456-
customComponentDialog.OnBackPressedDispatcher.OnBackPressed();
461+
_ = _modalNavigationManager?.PopModalAsync(true);
457462
}
458463

459464
eventHandler = null;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[Issue(IssueTracker.Github, 28811, "Overriding back button functionality with OnBackButtonPressed returning false in a modally pushed page causes stack overflow", PlatformAffected.Android)]
2+
public class Issue28811 : ContentPage
3+
{
4+
public Issue28811()
5+
{
6+
Content = new Button()
7+
{
8+
AutomationId = "NavigateToDetailPage",
9+
HeightRequest = 50,
10+
Text = "Navigate to Detail Page",
11+
Command = new Command(() => Navigation.PushModalAsync(new Issue28811DetailPage()))
12+
};
13+
}
14+
15+
class Issue28811DetailPage : ContentPage
16+
{
17+
public Issue28811DetailPage()
18+
{
19+
Content = new Label()
20+
{
21+
AutomationId = "Issue28811DetailPage",
22+
Text = "Hello, World!",
23+
};
24+
}
25+
26+
protected override bool OnBackButtonPressed()
27+
{
28+
return false;
29+
}
30+
}
31+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using NUnit.Framework;
2+
using UITest.Appium;
3+
using UITest.Core;
4+
5+
namespace Microsoft.Maui.TestCases.Tests.Issues;
6+
public class Issue28811 : _IssuesUITest
7+
{
8+
public Issue28811(TestDevice testDevice) : base(testDevice)
9+
{
10+
}
11+
12+
public override string Issue => "Overriding back button functionality with OnBackButtonPressed returning false in a modally pushed page causes stack overflow";
13+
14+
[Test]
15+
[Category(UITestCategories.Navigation)]
16+
public void OverridingBackButtonShouldNotCauseStackOverflow()
17+
{
18+
App.WaitForElement("NavigateToDetailPage");
19+
App.Click("NavigateToDetailPage");
20+
App.WaitForElement("Issue28811DetailPage");
21+
App.Back();
22+
App.WaitForElement("NavigateToDetailPage");
23+
}
24+
}

0 commit comments

Comments
 (0)