locked
Xamarin.Forms: Changing TabbedPage tab icons depending on active/inactive RRS feed

  • Question

  • User372619 posted

    Hey guys!

    I'm working on a Xamarin.Forms project and I'm trying to change the icons of the TabbedPage tabs depending on whether the tab is active or inactive. I have gotten it to work on iOS with the following code, but for some unknown reason it doesn't work on Android.

    MainPage.xaml

    <TabbedPage xmlns:Views="clr-namespace:Project.Views" x:Class="Project.Views.MainPage">
        <NavigationPage x:Name="HomeTab" Title="Home" Icon="home_inactive.png">
            <x:Arguments>
                <Views:Home/>
            </x:Arguments>
        </NavigationPage>
        <NavigationPage x:Name="FavoritesTab" Title="Favorites" Icon="favorites_inactive.png">
            <x:Arguments>
                <Views:Favorites/>
            </x:Arguments>
        </NavigationPage>
        <NavigationPage x:Name="AlertsTab" Title="Alerts" Icon="alerts_inactive.png">
            <x:Arguments>
                <Views:Alerts/>
            </x:Arguments>
        </NavigationPage>
        <NavigationPage x:Name="AccountTab" Title="Account" Icon="account_inactive.png">
            <x:Arguments>
                <Views:Account/>
            </x:Arguments>
        </NavigationPage>
        <NavigationPage x:Name="TestViewTab" Title="TestView">
            <x:Arguments>
                <Views:TestView/>
            </x:Arguments>
        </NavigationPage>
    </TabbedPage>
    

    MainPage.xaml.cs

    public partial class MainPage : TabbedPage
    {
        public MainPage()
        {
    
            InitializeComponent();
    
            this.CurrentPageChanged += (object sender, EventArgs e) => {
    
                var i = this.Children.IndexOf(this.CurrentPage);
    
                HomeTab.Icon = "home_inactive.png";
                FavoritesTab.Icon = "favorites_inactive.png";
                AlertsTab.Icon = "alerts_inactive.png";
                AccountTab.Icon = "account_inactive.png";
    
                switch (i)
                {
                    case 0:
                        HomeTab.Icon = "home_active.png";
                        break;
                    case 1:
                        FavoritesTab.Icon = "favorites_active.png";
                        break;
                    case 2:
                        AlertsTab.Icon = "alerts_active.png";
                        break;
                    case 3:
                        AccountTab.Icon = "account_active.png";
                        break;
                }
    
            };
    
        }
    
    }
    

    Using the CurrentPageChanged event works perfectly for iOS, but for some reason it doesn't work on Android. If I change something like Title instead of Icon, then it'll work on both iOS and Android.

    How would I go about fixing this so it works on both Android and iOS? Can I do it all in shared code? If not, could someone walk me through creating platform specific code to do the job?

    I would very much appreciate if you guys could help me out! Thanks in advance!

    Tuesday, August 21, 2018 4:27 PM

Answers

  • User364855 posted

    @Amigoman

    To achieve it in android, you need to use the [custom renderer(https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/). And use the OnTabSelected and OnTabUnselected event in TabLayout.IOnTabSelectedListener to change the icon. For example:

    [assembly:ExportRenderer(typeof(TabbedPage),typeof(MyTabbedpageRender))]
    namespace ChangingTabbedPageicons.Droid
    {
        public class MyTabbedpageRender : TabbedPageRenderer, TabLayout.IOnTabSelectedListener
        {
            public MyTabbedpageRender(Context context) : base(context)
            {
    
            }
            void TabLayout.IOnTabSelectedListener.OnTabSelected(TabLayout.Tab tab)
            {
                if (tab == null)
                {
                    return;
                }
    
                switch (tab.Text)
                {
                    case "Home":
                        tab.SetIcon(Resource.Drawable.Icon);
                        break;
                    case "Favorites":
                        tab.SetIcon(Resource.Drawable.Icon);
                        break;
                    default:
                        break;         
                }
            }
    
            void TabLayout.IOnTabSelectedListener.OnTabUnselected(TabLayout.Tab tab)
            {
                if (tab == null)
                {
                    return;
                }
                switch (tab.Text)
                {
                    case "Home":
                        tab.SetIcon(Resource.Drawable.xamarin_logo);
                        break;
                    case "Favorites":
                        tab.SetIcon(Resource.Drawable.xamarin_logo);
                        break;
                    default:
                        break;
                }
            }
        }
    }
    

    And the result is:

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, August 23, 2018 6:05 AM

All replies

  • User364855 posted

    @Amigoman

    To achieve it in android, you need to use the [custom renderer(https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/). And use the OnTabSelected and OnTabUnselected event in TabLayout.IOnTabSelectedListener to change the icon. For example:

    [assembly:ExportRenderer(typeof(TabbedPage),typeof(MyTabbedpageRender))]
    namespace ChangingTabbedPageicons.Droid
    {
        public class MyTabbedpageRender : TabbedPageRenderer, TabLayout.IOnTabSelectedListener
        {
            public MyTabbedpageRender(Context context) : base(context)
            {
    
            }
            void TabLayout.IOnTabSelectedListener.OnTabSelected(TabLayout.Tab tab)
            {
                if (tab == null)
                {
                    return;
                }
    
                switch (tab.Text)
                {
                    case "Home":
                        tab.SetIcon(Resource.Drawable.Icon);
                        break;
                    case "Favorites":
                        tab.SetIcon(Resource.Drawable.Icon);
                        break;
                    default:
                        break;         
                }
            }
    
            void TabLayout.IOnTabSelectedListener.OnTabUnselected(TabLayout.Tab tab)
            {
                if (tab == null)
                {
                    return;
                }
                switch (tab.Text)
                {
                    case "Home":
                        tab.SetIcon(Resource.Drawable.xamarin_logo);
                        break;
                    case "Favorites":
                        tab.SetIcon(Resource.Drawable.xamarin_logo);
                        break;
                    default:
                        break;
                }
            }
        }
    }
    

    And the result is:

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, August 23, 2018 6:05 AM
  • User155041 posted

    @BillyLiu

    Thank you Simple and Perfect Solution

    Saturday, October 13, 2018 6:35 PM
  • User370028 posted

    @BillyLiu I'm trying to do something similar but for some reason, OnTabSelected and OnTabUnselected are not called. I looked a little bit on google and it looks like it might need a TabLayout and set a IOnTabSelectedListener to the given TabLayout.

    Did something change since this your answer or I might be doing something wrong? (using XF 3.4)

    Wednesday, December 5, 2018 1:58 PM
  • User155041 posted

    @fabby329 said: @BillyLiu I'm trying to do something similar but for some reason, OnTabSelected and OnTabUnselected are not called. I looked a little bit on google and it looks like it might need a TabLayout and set a IOnTabSelectedListener to the given TabLayout.

    Did something change since this your answer or I might be doing something wrong? (using XF 3.4)

    i think your using BottomNavigationBar , so they dont work !

    if your using TopNavigation bar make sure your using TabbedPageRenderer

    Wednesday, December 5, 2018 2:42 PM
  • User370028 posted

    @Charwaka that's right, thanks for the clarification.

    Wednesday, December 5, 2018 4:53 PM