Add Custom Back Button on Android

Ok, first of all, this post is actually a complementary post of my previous post, Changing Navigation Bar Color Dynamically. In that post we discussed about how to change the color of the navigation bar when we navigate to different menu. At the end of that post, I gave external reference about how to override back button. That overriding back button method solved almost all the problem we had about back button. Unless one thing. In Android, changing the navigation bar color give us a navigation bar without back button. We still could navigate with device back button, but normally an Android app will have back button on its navigation bar. So, in this post we will discuss how to add our own back button and we will override it, just like we did in previous post.

Accessing Toolbar from Page Renderer

To create custom back button and adding it to the page, obviously we gonna need custom renderer. But, there’s one little problem. In Android, the navigation bar is actually a toolbar and we can not access it freely from the renderer. We need to have access first to the activity, and then we access the toolbar. And in doing so, I got tremendous help from Xamarin Forum. We just to add this following codes to MainActivity.cs

private static MainActivity _this;
public static View RootFindViewById<T>(int id) where T : View
{
    return _this.FindViewById<T>(id);
}
public MainActivity()
{
    _this = this;
}

Customize Android Logo

After we’ve done with the MainActivity, now we’ll create the page renderer. The page renderer will render the CoolContentPage that we discuss in the previous post. In this page renderer, we’ll customize the Android Logo. Android Logo is toolbar component that’s placed between back button and toolbar title. And with we having no back button in this case, android logo become most left placed component on the toolbar. And, fortunately, android logo is basically an ImageView, little bit different with the regular ImageView, but still, like an ImageView, we can set an image and adding listener to it. And this is exactly what we gonna do. First, add an Android back button image to Drawable folder, and then create CoolContentPage custom renderer with the following code.

public class CoolContentPageRenderer : PageRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
    {
        base.OnElementChanged(e);
        if (((CoolContentPage)Element).EnableBackButtonOverride)
        {
            SetCustomBackButton();
        }
    }
    private void SetCustomBackButton()
    {
        //accessing toolbar from MainActivity
        var toolbar = (Toolbar)MainActivity.RootFindViewById<Toolbar>(Resource.Id.toolbar);

        // set Android Logo's image
        toolbar.SetLogo(Resource.Drawable.AndroidBackButton);

        for (int i = 0; i < toolbar.ChildCount; i++)
        {
            var item = toolbar.GetChildAt(i);
            //if Android Logo
            if (item.GetType() == typeof(AppCompatImageView))
            {
                AppCompatImageView image = (AppCompatImageView)item;
                image.Click += (sender, e) =>
                {
                    if (((CoolContentPage)Element)?.CustomBackButtonAction != null)
                    {
                        ((CoolContentPage)Element)?.CustomBackButtonAction.Invoke();
                    }
                };
            }
        }
    }
}

Navigation Handling

Now that’s all set, we just need to do little update to the content page. Just like I stated earlier, this post is complementary of my previous post, so I’ll give example from my previous post as well. In that post, we created breakfast page menu with overriding back button. And customizing android logo will have massive effect to breakfast page.

Let’s take one page for example. Let say we navigate to Sandwich Page, of course it gonna have customized android logo. And then we navigate to other page from Sandwich Page, that page will still have the android logo. Event hough we don’t inherit that CoolContentPage. Yes, once we set it, Android logo stays still. It will be a problem if the next page already has natural back button, so the page will have two back buttons. And even worse, the android logo back button won’t even follow the natural order of navigation stack. It will still execute the listener we set on page renderer.

To avoid such kind of problem, we need to update our breakfast page. Here’s the example how I did it.

public partial class BreakfastSandwich : CoolContentPage
{
    public BreakfastSandwich()
    {
        InitializeComponent();
        if (EnableBackButtonOverride)
        {
            this.CustomBackButtonAction = () =>
            {
                 var currentpage = Application.Current.MainPage.Navigation.NavigationStack.LastOrDefault();
                 // if root page
                 if(currentpage.GetType() ==typeof(BreakfastSandwich))
                 {
                    Application.Current.MainPage = new BreakfastPage();
                 }
                 else
                 {
                    Navigation.PopAsync();
                 }
            };
        }
    }
}

And for any pages that Breakfast Sandwich navigate into, we have to remove the natural back button, so we don’t have double back button on the toolbar.  We’ll only do it in Android, because Android Logo won’t have any effect on iOS platform. Here’s the example.

public partial class MoreSandwichPage : ContentPage
{
    public MoreSandwichPage()
    {
        InitializeComponent();
        if (Device.RuntimePlatform == Device.Android)
        {
            NavigationPage.SetHasBackButton(this, false);
        }
    }
}

Note : For simplicity sake, I used raw icon I got from FlatIcon, in real project you should use customize back button icon that has space after the arrow, in order to make it look like real Android back button.

 

Credit:

  • Icon from FlatIcon, Left Arrow icon by Google
  • Override Navigation Back Button by Udara Alwis (blog)
  • Access Toolbar from Page Renderer by ChaseFlorell (Xamarin Forum)
  • Get Android Logo from Toolbar by Mike M. (StackOverflow)
Advertisements

One thought on “Add Custom Back Button on Android

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s