0
votes

When using a navigation drawer (i.e. Hamburger Menu) in an Android App, the Xamarin Shell Navigation has for most users a confusing default behavior of the hardware back button.

Whenever I navigate to a page (FlyoutItem) from the menu and then hit the hardware back button, the app closes and the phone is back in the launcher screen. But I thought the back button should go to the last shown screen or the start screen.

Apps from Google, like the Play Store or Gmail or Album App from Sony will navigate back to the start screen of the app when hitting the hardware back button. Then hitting the back button on the start screen will close the app. This is my expected behavior of Shell navigation. Gmail and Album always show the hamburger menu icon, others replace hamburger by a back icon/arrow.

What would be a preferred way of getting to the start page when using hardware back button?

An option I thought so far is overriding the OnBackButtonPressed in the xaml.cs. Can the BackButtonBehavior of Shell be used?

2

2 Answers

1
votes

Instead of FlyoutItem use MenuItem

For ex.: AppShell.xaml

<Shell....>
    <MenuItem Text="bears"
        Icon="bear.png"
        Command="{Binding BearsPageCommand}" />
.
.
.
</Shell>

AppShell.xaml.cs

public ICommand BearsPageCommand => new Command(async () => await NavigateToBearsPageAsync());

async Task NavigateToBearsPageAsync()
{
    ShellNavigationState state = Shell.Current.CurrentState;
    await Shell.Current.Navigation.PushAsync(new BearsPage());
    Shell.Current.FlyoutIsPresented = false;
}
0
votes

you can override OnBackPressed in Android MainActivity class. In that method I use Messaging center to send a 'BackButtonPressed' message. In my shell view model I then subscribe to this message and on receipt navigate to my home page.

In MainActivity:

public override void OnBackPressed()
    {
        //currently hitting back button terminates the whole app, not navigating back
        //instead let's make it navigate back to the home page and not close the app!
        //also serves as workaround for the Shell exception on back button pressed
        var msg = new BackButtonPressedMessage();
        MessagingCenter.Send(msg, "BackButtonPressedMessage");

    }

Then in view model:

void WireUpBackButon()
    {
        //listen for hardware back button presses from Android
        MessagingCenter.Subscribe<BackButtonPressedMessage>(this, "BackButtonPressedMessage", async message =>
        {
            await Shell.Current.GoToAsync("//home");
        });
    }