How to disable arrow to hamburger transition animation on Android?

Pierre-ChristopheDusPierre-ChristopheDus FRUniversity ✭✭✭
edited April 2018 in Xamarin.Forms

Hello,

I've created a basic sample app with Xamarin.Forms, where I tried to repoduce a UI like Twitter or Instagram with:

  • a MasterDetail page as main page, where the default "hamburger" icon is replaced by a custom icon
  • a "bottom" TabbedPage as detail of the MasterDetail page
  • a control allowing to implement top Tabs in the TabbedPage
  • ContentPages that are hosted in NavigationPage for each tab of the TabbedPage

So, the the pages architecture of my app looks like this:

|-- MasterDetailpage
..|--TabbedPage
.....|-- NavigationPage
........|-- ContentPage

For achieving this, I've used:

  • the Naxam BottomTabedPage, to implement "bottom" TabbedPage on Android (like BottomNavigationView)
  • the Syncfusion SfTabView control to implement the "top" Tabs
  • a custom renderer to manage the use of custom icon as "hamburger" icon on the main level, and the "arrow" icon on the childs levels

This renderer looks like this:

public class CustomNavigationPageRenderer : MasterDetailPageRenderer
{
    protected override void OnLayout(bool changed, int l, int t, int r, int b)
    {
        base.OnLayout(changed, l, t, r, b);
        var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);

        for (var i = 0; i < toolbar.ChildCount; i++)
        {
            var imageButton = toolbar.GetChildAt(i) as ImageButton;
            var drawerArrow = imageButton?.Drawable as DrawerArrowDrawable;
            if (drawerArrow == null)
                continue;

            bool displayBack = false;
            var app = Xamarin.Forms.Application.Current;
            //var navPage = ((app.MainPage.Navigation.ModalStack[0] as MasterDetailPage).Detail as NavigationPage);
            var detailPage = (app.MainPage as MasterDetailPage).Detail;
            if (detailPage.GetType() == typeof(BottomTp.Views.NaxamMainPage))
            {
                var tabPage = detailPage as BottomTabbedPage;
                var curPage = tabPage.CurrentPage;
                var navPageLevel = curPage.Navigation.NavigationStack.Count;
                if (navPageLevel > 1)
                    displayBack = true;
            }

            if (!displayBack)
                ChangeIcon(imageButton, Resource.Drawable.icon);
        }
    }

    private void ChangeIcon(ImageButton imageButton, int id)
    {
        if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
            imageButton.SetImageDrawable(Context.GetDrawable(id));
        imageButton.SetImageResource(id);
    }
}

This works well, but I get a last problem when I "return" to the main page:

  • there is the default transition animation from arrow to "hamburger" icon
  • after this, the "hamburger" icon is replaced by my custom icon

Here is a short animation to describe this issue:

Is there a way to deactivate this animation? How could I fix this?

Best Answer

  • Pierre-ChristopheDusPierre-ChristopheDus FR ✭✭✭
    edited April 2018 Accepted Answer

    Someone helped me to fix this on Stackoverflow, so I give here the solution:

    1. Create a custom control that inherits from NavigationPage:

      public class CustomNavigationPage : NavigationPage
      {
          public CustomNavigationPage() { }
          public CustomNavigationPage(Page root) : base(root) { }
      }
      
    2. Replace the default NavigationPage that are used in the TabbedPage with CustomNavigationPage

    3. Add this new renderer for the CustomNavigationPage control:

      [assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(CustomNavigationPageRenderer))]
      namespace BottomTp.Droid.Renderers
      {
          class CustomNavigationPageRenderer : NavigationPageRenderer
          {
              public CustomNavigationPageRenderer(Context c) : base(c)
              { }
      
              protected override Task<bool> OnPopToRootAsync(Page page, bool animated)
              {
                  return base.OnPopToRootAsync(page, false);
              }
      
              protected override Task<bool> OnPopViewAsync(Page page, bool animated)
              {
                  return base.OnPopViewAsync(page, false);
              }
      
              protected override Task<bool> OnPushAsync(Page view, bool animated)
              {
                  return base.OnPushAsync(view, false);
              }
      
          }
      }
      

    The code of my sample on GitHub has been updated with the latest changes. There is also a basic sample, without TabbedPage or TabsControl.

Answers

  • Pierre-ChristopheDusPierre-ChristopheDus FRUniversity ✭✭✭
    edited April 2018 Accepted Answer

    Someone helped me to fix this on Stackoverflow, so I give here the solution:

    1. Create a custom control that inherits from NavigationPage:

      public class CustomNavigationPage : NavigationPage
      {
          public CustomNavigationPage() { }
          public CustomNavigationPage(Page root) : base(root) { }
      }
      
    2. Replace the default NavigationPage that are used in the TabbedPage with CustomNavigationPage

    3. Add this new renderer for the CustomNavigationPage control:

      [assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(CustomNavigationPageRenderer))]
      namespace BottomTp.Droid.Renderers
      {
          class CustomNavigationPageRenderer : NavigationPageRenderer
          {
              public CustomNavigationPageRenderer(Context c) : base(c)
              { }
      
              protected override Task<bool> OnPopToRootAsync(Page page, bool animated)
              {
                  return base.OnPopToRootAsync(page, false);
              }
      
              protected override Task<bool> OnPopViewAsync(Page page, bool animated)
              {
                  return base.OnPopViewAsync(page, false);
              }
      
              protected override Task<bool> OnPushAsync(Page view, bool animated)
              {
                  return base.OnPushAsync(view, false);
              }
      
          }
      }
      

    The code of my sample on GitHub has been updated with the latest changes. There is also a basic sample, without TabbedPage or TabsControl.

Sign In or Register to comment.