Hadi Fooladi Talari
Hadi Fooladi Talari

Reputation: 1278

How to prompt for exit when back button is pressed?

Recently I had to add a feature to a Xamarin Forms mobile application. The feature shows a yes/no prompt when the user presses the back button (in Android phones). If the user selects No it will discard the button, otherwise, it will apply the back button which will hide the application.

I knew that for detecting the back button in Xamarin Forms I have to override the Page.OnBackButtonPressed method. And for bypassing the back button it should return true, like this:

protected override bool OnBackButtonPressed()
{
    if (DisplayAlert("", "Are you sure?", "Yes", "No"))
        return false;

    return true;
}

But the problem lies in the fact that Page.DisplayAlert is an async method and must be called on the main (UI) thread. So after a lot of searches, I came up with this idea which I want to share.

I'm open to any ideas/suggestions on how to improve.

Upvotes: 3

Views: 3240

Answers (1)

Hadi Fooladi Talari
Hadi Fooladi Talari

Reputation: 1278

I think the answer is emulating the back button after getting the result of DisplayAlert.

For emulating the back button I found calling Activity.OnBackPressed useful.

For sure it is not the best idea but it is easy to call this method in Shared/PCL Xamarin Forms project in this manner:

  1. Defining a public static Action field somewhere (e.g. the page)
  2. Initializing this field in the MainActivity class by OnBackPressed

So the whole solution would be like this:

Xamarin Forms Page Class

class MyPage : ContentPage
{
    public static Action EmulateBackPressed;

    private bool AcceptBack;

    protected override bool OnBackButtonPressed()
    {
        if (AcceptBack)
            return false;

        PromptForExit();
        return true;
    }

    private async void PromptForExit()
    {
        if (await DisplayAlert("", "Are you sure to exit?", "Yes", "No"))
        {
            AcceptBack = true;
            EmulateBackPressed();
        }
    }
}

Xamarin Android MainActivity Class

public class MainActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        MyPage.EmulateBackPressed = OnBackPressed;

        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(bundle);

        Xamarin.Forms.Forms.Init(this, bundle);
        LoadApplication(new App());
    }
}

Upvotes: 8

Related Questions