Home > OS >  Override navbar back button click on Xamarin.Forms
Override navbar back button click on Xamarin.Forms

Time:01-15

Is there any way to show an alert msg before clicking navbar back icon & exiting the page. I've tried this solution but it's not working.

CodePudding user response:

If you want to capture the back button click the Action Bar in android platform, you can try to override the OnOptionsItemSelected() in the MainActivity class, which allows us to capture the navigation bar’s back button click.

Please follow up the following steps:

1.create a base contentpage CoolContentPage.cs

public class CoolContentPage: ContentPage 
{
    /// <summary>
    /// Gets or Sets the Back button click overriden custom action
    /// </summary>
    public Action CustomBackButtonAction { get; set; }

    public static readonly BindableProperty EnableBackButtonOverrideProperty =
           BindableProperty.Create(
           nameof(EnableBackButtonOverride),
           typeof(bool),
           typeof(CoolContentPage),
           false);

    /// <summary>
    /// Gets or Sets Custom Back button overriding state
    /// </summary>
    public bool EnableBackButtonOverride
    {
        get
        {
            return (bool)GetValue(EnableBackButtonOverrideProperty);
        }
        set
        {
            SetValue(EnableBackButtonOverrideProperty, value);
        }
    }
}

2.override the OnOptionsItemSelected() event in MainActivity class in order to capture the nav bar back button click in Android for Xamarin Forms.

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        //TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);

        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());

        AndroidX.AppCompat.Widget.Toolbar toolbar
            = this.FindViewById<AndroidX.AppCompat.Widget.Toolbar>(Resource.Id.toolbar);
        SetSupportActionBar(toolbar);
    }

    public override bool OnOptionsItemSelected(IMenuItem item)
    {
        // check if the current item id 
        // is equals to the back button id
        if (item.ItemId == 16908332) // xam forms nav bar back button id
        {
            // retrieve the current xamarin 
            // forms page instance
            var currentpage = (CoolContentPage)Xamarin.Forms.Application.Current.
                 MainPage.Navigation.NavigationStack.LastOrDefault();

            // check if the page has subscribed to the custom back button event
            if (currentpage?.CustomBackButtonAction != null)
            {
                // invoke the Custom back button action
                currentpage?.CustomBackButtonAction.Invoke();
                // and disable the default back button action
                return false;
            }

            // if its not subscribed then go ahead 
            // with the default back button action
            return base.OnOptionsItemSelected(item);
        }
        else
        {
            // since its not the back button 
            //click, pass the event to the base
            return base.OnOptionsItemSelected(item);
        }
    }

    public override void OnBackPressed()
    {
        // this is really not necessary, but in Android user has both Nav bar back button 
        // and physical back button, so its safe to cover the both events

        var currentpage = (CoolContentPage)Xamarin.Forms.Application.Current.
            MainPage.Navigation.NavigationStack.LastOrDefault();

        if (currentpage?.CustomBackButtonAction != null)
        {
            currentpage?.CustomBackButtonAction.Invoke();
        }
        else
        {
            base.OnBackPressed();
        }
    }
    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    {
        Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

Here, we need to create Toolbar.xml in folder layout

Toolbar.xml

<androidx.appcompat.widget.Toolbar 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@ id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

3.In xamarin forms,we can use CoolContentPage we created above as a XAML page in Xamarin Forms solution:

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?> 
<xfbackbtnapp:CoolContentPage  xmlns:xfbackbtnapp="clr-namespace:XFBackBtnApp"
                               xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XFBackBtnApp.MainPage"
             EnableBackButtonOverride="False"
             Title="Home Page"
             BackgroundColor="#00bfff"                  
                               >

    <StackLayout
    Spacing="20"
    Padding="20,10,20,10"
    VerticalOptions="Center"
    HorizontalOptions="Center" >

        <Label Text="Welcome to Navigation Bar Back button Click overriding in Xamarin Forms!"
           FontSize="20"
           HorizontalTextAlignment="Center"
           TextColor="White"/>

        <Button Text="Open Next Page" FontSize="15" BackgroundColor="White" Clicked="OpenPageButton_OnClicked"></Button>

    </StackLayout>

</xfbackbtnapp:CoolContentPage>

MainPage.xaml.cs

public partial class MainPage : CoolContentPage 
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void OpenPageButton_OnClicked(object sender, EventArgs e)
    {
        Navigation.PushAsync(new Page1());
    }
}

Page1.xaml

<?xml version="1.0" encoding="utf-8" ?> 
<xfbackbtnapp:CoolContentPage  xmlns:xfbackbtnapp="clr-namespace:XFBackBtnApp" 
                               xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
              EnableBackButtonOverride="False"
             BackgroundColor="#00bfff"
             Title="Page 1"
             x:Class="XFBackBtnApp.Page1">
    <ContentPage.Content>
        <StackLayout
    Spacing="20"
    Padding="20,10,20,10"
    VerticalOptions="Center"
    HorizontalOptions="Center" >

            <Label Text="Ok, this is just a normal Page! Click next Page to see the Navigation Bar Back button click overridden behavior..."
           FontSize="20"
           HorizontalTextAlignment="Center"
           TextColor="White"/>

            <Button Text="Open Next Page" FontSize="15" BackgroundColor="White" Clicked="OpenPageButton_OnClicked"></Button>

        </StackLayout>
    </ContentPage.Content>
</xfbackbtnapp:CoolContentPage>

Page1.xaml.cs

public partial class Page1 : CoolContentPage 
{
    public Page1()
    {
        InitializeComponent();
    }

    private void OpenPageButton_OnClicked(object sender, EventArgs e)
    {
        Navigation.PushAsync(new Page2());
    }
}

Page2.xaml

<?xml version="1.0" encoding="utf-8" ?> 
<xfbackbtnapp:CoolContentPage  xmlns:xfbackbtnapp="clr-namespace:XFBackBtnApp"
                               xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XFBackBtnApp.Page2"
             EnableBackButtonOverride="True"
             BackgroundColor="#00bfff"         
             Title="Page 2"
                               
                               >
    <ContentPage.Content>
        <StackLayout
    Spacing="20"
    Padding="20,10,20,10"
    VerticalOptions="Center"
    HorizontalOptions="Center" >

            <Label Text="This is the cool page, which has the Navigation Bar Back button click overriden. How go ahead and click that Back button! ;)"
           FontSize="20"
           HorizontalTextAlignment="Center"
           TextColor="White"/>

        </StackLayout>
    </ContentPage.Content>
</xfbackbtnapp:CoolContentPage>

Page2.xaml.cs

   public partial class Page2 : CoolContentPage 
{
    public Page2()
    {
        InitializeComponent();

        if (EnableBackButtonOverride)
        {
            this.CustomBackButtonAction = async () =>
            {
                var result = await this.DisplayAlert(null,
                    "Hey wait now! are you sure "  
                    "you want to go back?",
                    "Yes go back", "Nope");

                if (result)
                {
                    await Navigation.PopAsync(true);
                }
            };
        }
    }
}

Note:

1.Here,I added property EnableBackButtonOverride="True" to the root of Page2.xaml, then if we can press the back button of the Toolbar on the top of the page or press the soft back button of our Phone, a DisplayAlert will pop up.

2.If you want to achieve this function in Ios,you can check article Override Navigation Bar back button click in Xamarin Forms.

  • Related