Skip to content

Commit

Permalink
Merge pull request #3181 from PrismLibrary/goback
Browse files Browse the repository at this point in the history
fixing Android hardware button
  • Loading branch information
dansiegel authored Jul 5, 2024
2 parents e64870b + 4d26911 commit 90a701f
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 52 deletions.
8 changes: 7 additions & 1 deletion e2e/Maui/MauiModule/ViewModels/ViewModelBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace MauiModule.ViewModels;

public abstract class ViewModelBase : BindableBase, IInitialize, INavigatedAware, IPageLifecycleAware
public abstract class ViewModelBase : BindableBase, IInitialize, INavigatedAware, IPageLifecycleAware, IConfirmNavigation
{
protected INavigationService _navigationService { get; }
protected IPageDialogService _pageDialogs { get; }
Expand Down Expand Up @@ -109,4 +109,10 @@ public void OnDisappearing()
{
Messages.Add("View Disappearing");
}

public virtual bool CanNavigate(INavigationParameters parameters)
{
Messages.Add("Can Navigate");
return true;
}
}
40 changes: 25 additions & 15 deletions e2e/Maui/PrismMauiDemo/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,31 @@ public static MauiApp CreateMauiApp()
if (status == "Failed" && !string.IsNullOrEmpty(x.Result?.Exception?.Message))
Console.Error.WriteLine(x.Result.Exception.Message);
}))
//.CreateWindow(nav => nav.CreateBuilder()
// .AddTabbedSegment(page =>
// page.CreateTab("ViewC")
// .CreateTab(t =>
// t.AddNavigationPage()
// .AddSegment("ViewA", s => s.AddParameter("message", "Hello Tab - ViewA"))
// .AddSegment("ViewB", s => s.AddParameter("message", "Hello Tab - ViewB")))
// //.CreateTab("ViewC", s => s.AddParameter("message", "Hello Tab - ViewC"))
// .SelectedTab("NavigationPage|ViewB"))
// .AddParameter("message_global", "This is a Global Message")
// .Navigate())
//.CreateWindow("ViewA/ViewB/ViewC")
.CreateWindow(navigationService => navigationService.CreateBuilder()
.AddSegment<SplashPageViewModel>()
.NavigateAsync(HandleNavigationError))
//.CreateWindow(nav => nav.CreateBuilder()
// .AddTabbedSegment(page =>
// page.CreateTab("ViewC")
// .CreateTab(t =>
// t.AddNavigationPage()
// .AddSegment("ViewA", s => s.AddParameter("message", "Hello Tab - ViewA"))
// .AddSegment("ViewB", s => s.AddParameter("message", "Hello Tab - ViewB")))
// //.CreateTab("ViewC", s => s.AddParameter("message", "Hello Tab - ViewC"))
// .SelectedTab("NavigationPage|ViewB"))
// .AddParameter("message_global", "This is a Global Message")
// .Navigate())
//.CreateWindow("ViewA/ViewB") //broken
//.CreateWindow("NavigationPage/TabbedPage?createTab=ViewB/ViewC") //works
//.CreateWindow("ViewA/NavigationPage/TabbedPage?createTab=ViewB/ViewC") //works
//.CreateWindow(nav => nav
// .CreateBuilder()
// .AddTabbedSegment(page =>
// page.CreateTab(t =>
// t.AddNavigationPage()
// .AddSegment("ViewA")
// .AddSegment("ViewB")))
// .NavigateAsync()) //works
.CreateWindow(navigationService => navigationService.CreateBuilder()
.AddSegment<SplashPageViewModel>()
.NavigateAsync(HandleNavigationError))
)
.ConfigureFonts(fonts =>
{
Expand Down
25 changes: 6 additions & 19 deletions src/Maui/Prism.Maui/Controls/PrismNavigationPage.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Prism.Common;
using Prism.Common;
using Prism.Navigation;
using UIModalPresentationStyle = Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific.UIModalPresentationStyle;

Expand All @@ -12,34 +12,21 @@ public class PrismNavigationPage : NavigationPage
/// <summary>
/// Creates a new instance of the <see cref="PrismNavigationPage"/>
/// </summary>
public PrismNavigationPage()
{
BackButtonPressed += HandleBackButtonPressed;
}
public PrismNavigationPage() { }

/// <summary>
/// Creates a new instance of the <see cref="PrismNavigationPage"/> with a specified <see cref="Page"/> at the Root
/// </summary>
/// <param name="page"></param>
public PrismNavigationPage(Page page)
: base(page)
{
BackButtonPressed += HandleBackButtonPressed;
}
{ }

/// <inheritdoc/>
public event EventHandler BackButtonPressed;

/// <inheritdoc/>
protected override bool OnBackButtonPressed()
{
BackButtonPressed.Invoke(this, EventArgs.Empty);
return false;
}

private async void HandleBackButtonPressed(object sender, EventArgs args)
protected sealed override bool OnBackButtonPressed()
{
await MvvmHelpers.HandleNavigationPageGoBack(this);
MvvmHelpers.HandleNavigationPageGoBack(this).ConfigureAwait(false);
return true; //Prism will always handle the navigation
}

#if IOS
Expand Down
13 changes: 7 additions & 6 deletions src/Maui/Prism.Maui/Navigation/PageNavigationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
using System.Web;
using Prism.Common;
using Prism.Events;
using Prism.Extensions;
using Prism.Mvvm;
using Prism.Navigation.Regions;
using Application = Microsoft.Maui.Controls.Application;
using XamlTab = Prism.Navigation.Xaml.TabbedPage;

Expand Down Expand Up @@ -100,10 +98,6 @@ private async Task<INavigationResult> GoBackInternalAsync(INavigationParameters
NavigationSource = PageNavigationSource.NavigationService;

page = GetCurrentPage();
if (IsRoot(GetPageFromWindow(), page))
{
return SendAppToBackground(page);
}

parameters.GetNavigationParametersInternal().Add(KnownInternalParameters.NavigationMode, NavigationMode.Back);

Expand All @@ -113,6 +107,11 @@ private async Task<INavigationResult> GoBackInternalAsync(INavigationParameters
throw new NavigationException(NavigationException.IConfirmNavigationReturnedFalse, page);
}

if (IsRoot(GetPageFromWindow(), page))
{
return SendAppToBackground(page);
}

bool useModalForDoPop = UseModalGoBack(page, parameters);
Page previousPage = MvvmHelpers.GetOnNavigatedToTarget(page, Window?.Page, useModalForDoPop);

Expand Down Expand Up @@ -1249,6 +1248,8 @@ private bool GoBackModal(NavigationPage navPage)
return true;
else if (navPage.Parent is TabbedPage tabbed && tabbed != rootPage)
return true;
else if (rootPage != navPage || IsRoot(rootPage, navPage.CurrentPage))
return true;

return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Maui/Prism.Maui/Navigation/PrismWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ public void OnSystemBack()
if (dialogContainer.Dismiss.CanExecute(null))
dialogContainer.Dismiss.Execute(null);
}
else
else if (PageNavigationService.NavigationSource == PageNavigationSource.Device)
{
var navigation = container.Resolve<INavigationService>();
navigation.GoBackAsync();
}
}

private bool IsRoot(Page page)
internal bool IsRoot(Page page)
{
if (page == Page) return true;

Expand Down
5 changes: 0 additions & 5 deletions src/Maui/Prism.Maui/PrismAppBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,6 @@ internal PrismAppBuilder(IContainerExtension containerExtension, MauiAppBuilder
if (window is null)
return false;
if (window.CurrentPage?.Parent is NavigationPage)
{
return true;
}
if(window.IsRootPage)
{
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
using Prism.DryIoc.Maui.Tests.Mocks.ViewModels;
using Prism.DryIoc.Maui.Tests.Mocks.Views;
using Prism.Navigation.Xaml;
using Prism.Navigation;
using Prism.Xaml;
using TabbedPage = Microsoft.Maui.Controls.TabbedPage;
using Microsoft.Maui.LifecycleEvents;

namespace Prism.DryIoc.Maui.Tests.Fixtures.Navigation;

Expand All @@ -31,7 +33,7 @@ public void PagesInjectScopedInstanceOfIPageAccessor(string uri)

var rootPage = window.Page;

if(rootPage is FlyoutPage flyoutPage)
if (rootPage is FlyoutPage flyoutPage)
{
TestPage(flyoutPage);
rootPage = flyoutPage.Detail;
Expand Down Expand Up @@ -660,6 +662,53 @@ public void Navigate_And_SelectTab(string selectTab, Type viewType)
Assert.IsType(viewType, child);
}

[Fact]
public async Task Issue3123_GoBack_SendsAppToBackground()
{
var errorInvoked = false;
var mauiApp = CreateBuilder(prism => prism
.AddGlobalNavigationObserver(context => context.Subscribe(x =>
{
//this error message is used in this unit test to know that the SendAppToBackground method was called
//for Android we send the app to the background and do not throw the exception, otherwise we throw and quit the app
if (!x.Result.Success && x.Result?.Exception?.Message == NavigationException.CannotPopApplicationMainPage)
errorInvoked = true;
}))
.CreateWindow(nav => nav.CreateBuilder()
.AddTabbedSegment(page =>
page.CreateTab(t =>
t.AddNavigationPage()
.AddSegment("MockViewA")
.AddSegment("MockViewB")))
.NavigateAsync()))
.Build();
var window = GetWindow(mauiApp);

var tabbedPage = window.Page as TabbedPage;
Assert.NotNull(tabbedPage);

var currentPage = tabbedPage.CurrentPage;
Assert.IsType<PrismNavigationPage>(currentPage);
Assert.Equal(2, currentPage.Navigation.NavigationStack.Count);

var navPage = (PrismNavigationPage)currentPage;
Assert.IsType<MockViewB>(navPage.CurrentPage);

var container = navPage.CurrentPage.GetContainerProvider();
var navService = container.Resolve<INavigationService>();
await navService.GoBackAsync();

Assert.False(errorInvoked);
Assert.IsType<MockViewA>(navPage.CurrentPage);
Assert.Single(currentPage.Navigation.NavigationStack);

container = navPage.CurrentPage.GetContainerProvider();
navService = container.Resolve<INavigationService>();
await navService.GoBackAsync();

Assert.True(errorInvoked);
}

private static void TestPage(Page page, bool ignoreNavigationPage = false)
{
Assert.NotNull(page.BindingContext);
Expand All @@ -672,7 +721,7 @@ private static void TestPage(Page page, bool ignoreNavigationPage = false)
Assert.NotNull(accessor.Page);
Assert.Same(page, accessor.Page);

if(page.Parent is not null)
if (page.Parent is not null)
{
Assert.False(page.BindingContext == page);
Assert.False(page.BindingContext == page.Parent);
Expand All @@ -691,7 +740,7 @@ private static void TestPage(Page page, bool ignoreNavigationPage = false)

if (page is TabbedPage tabbedPage)
{
foreach(var child in tabbedPage.Children)
foreach (var child in tabbedPage.Children)
{
TestPage(child, tabbedPage is MockExplicitTabbedPage);

Expand Down Expand Up @@ -735,7 +784,7 @@ private static void TestPageBehaviors(Page page)

Assert.Equal(expectedBehaviors, page.Behaviors.Count);

switch(page)
switch (page)
{
case TabbedPage:
TestTabbedPageBehaviors(page);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

<ItemGroup>
<ProjectReference Include="..\..\..\src\Maui\Prism.DryIoc.Maui\Prism.DryIoc.Maui.csproj" />
<ProjectReference Include="..\..\..\src\Maui\Prism.Maui.Rx\Prism.Maui.Rx.csproj" />
</ItemGroup>

</Project>

0 comments on commit 90a701f

Please sign in to comment.