2
votes

I'm playing with the COOL xamarin shell, but I didn't found a way to change icon of the selected tab.

<TabBar Route="sections">
    <Tab Title="home">
        <Tab.Icon>
            <FontImageSource FontFamily="{StaticResource AppIcons}" Glyph="{x:Static framework:Icons.HomePage}" />
        </Tab.Icon>
        <ShellContent ContentTemplate="{DataTemplate home:HomePage}" Route="home" />
    </Tab>

The goal is to use Icons.HomePageFilled instead of Icons.HomePage for this tab only when it's selected. Same logic should apply to other tabs.

I think I got lost in the solutions found on the web. They talk about Custom renderers(ShellTabLayoutAppearanceTracker), Visual states, effects etc ... But I do not know if it is feasible and what is the ideal solution

1
You can have the Icons.HomePage with the Background and solid thickness as transparent and then you can set the Shell.TabBarForegroundColor to the colour you want as Filled and the transparent part will be replaced with that colour. May be this should help!Nikhil

1 Answers

5
votes

You need to use custom renderer of shell to customize the tabbar selected icon on each platform.

In iOS, override the CreateTabBarAppearanceTracker method:

[assembly: ExportRenderer(typeof(AppShell), typeof(MyShellRenderer))]
namespace App30.iOS
{
    public class MyShellRenderer : ShellRenderer
    {
        protected override IShellSectionRenderer CreateShellSectionRenderer(ShellSection shellSection)
        {
            var renderer = base.CreateShellSectionRenderer(shellSection);
            if (renderer != null)
            {

            }
            return renderer;
        }

        protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
        {
            return new CustomTabbarAppearance();
        }
    }

    public class CustomTabbarAppearance : IShellTabBarAppearanceTracker
    {
        public void Dispose()
        {

        }

        public void ResetAppearance(UITabBarController controller)
        {

        }

        public void SetAppearance(UITabBarController controller, ShellAppearance appearance)
        {
            UITabBar myTabBar = controller.TabBar;

            if (myTabBar.Items != null)
            {
                UITabBarItem itemOne = myTabBar.Items[0];

                itemOne.Image = UIImage.FromBundle("tab_about.png");
                itemOne.SelectedImage = UIImage.FromBundle("tab_feed.png");


                UITabBarItem itemTwo = myTabBar.Items[1];

                itemTwo.Image = UIImage.FromBundle("tab_feed.png");
                itemTwo.SelectedImage = UIImage.FromBundle("tab_about.png");

                //The same logic if you have itemThree, itemFour....
            }

        }

        public void UpdateLayout(UITabBarController controller)
        {

        }
    }
}

In Android, override the CreateBottomNavViewAppearanceTracker method:

[assembly: ExportRenderer(typeof(AppShell), typeof(MyShellRenderer))]
namespace App30.Droid
{
    public class MyShellRenderer : ShellRenderer
    {
        public MyShellRenderer(Context context) : base(context)
        {
        }

        protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
        {
            return new CustomBottomNavAppearance();
        }
    }

    public class CustomBottomNavAppearance : IShellBottomNavViewAppearanceTracker
    {
        public void Dispose()
        {

        }

        public void ResetAppearance(BottomNavigationView bottomView)
        {

        }

        public void SetAppearance(BottomNavigationView bottomView, ShellAppearance appearance)
        {
            IMenu myMenu = bottomView.Menu;

            IMenuItem myItemOne = myMenu.GetItem(0);

            if (myItemOne.IsChecked)
            {
                myItemOne.SetIcon(Resource.Drawable.tab_about);
            }
            else
            {
                myItemOne.SetIcon(Resource.Drawable.tab_feed);
            }

            //The same logic if you have myItemTwo, myItemThree....

        }
    }
}

I uploaded a sample project here and you can check it.