xamarin.formsfontstabbarxamarin.shell

Xamarin.Forms with Shell: is there a way to specify a icon's color for active tab only?


I'm working on a Xamarin.Forms app based on Shell, and I'm using font icons as icons for the TabBar:

<TabBar>
    <ShellContent Title="Home" Route="HomePage" ContentTemplate="{DataTemplate local:HomePage}">
        <ShellContent.Icon>
            <FontImageSource Glyph="{StaticResource FasIconHome}" FontFamily="FontAwesomeSolid" />
        </ShellContent.Icon>
    </ShellContent>
</TabBar>

I would like to specify a color only for the active tab, but only for the icon, not for the text, as we can see on Airbnb: Airbnb screenshot

I didn't found any option in the Shell settings:

<Setter Property="Shell.BackgroundColor" Value="White" />
<Setter Property="Shell.ForegroundColor" Value="Black" />
<Setter Property="Shell.TitleColor" Value="Black" />
<Setter Property="Shell.DisabledColor" Value="{StaticResource Gray-300}" />
<Setter Property="Shell.UnselectedColor" Value="{StaticResource Gray-300}" />
<Setter Property="Shell.TabBarBackgroundColor" Value="White" />
<Setter Property="Shell.TabBarForegroundColor" Value="{StaticResource Gray-300}"/>
<Setter Property="Shell.TabBarUnselectedColor" Value="#95000000" />
<Setter Property="Shell.TabBarTitleColor" Value="Black" />

Is it possible?


Solution

  • In your case , you used FontImageSource to set the icon of tab item . However , if you want to set the color of a specific item icon , you need to download the icon with different color in advance and put the icon in both of native platform (Asset in iOS and Drawable in Android) . And set it by using Custom Renderer

    in iOS

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using xxx;
    using xxx.iOS;
    using Foundation;
    using UIKit;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.iOS;
    
    [assembly: ExportRenderer(typeof(AppShell), typeof(ShellCustomRenderer))]
    namespace xxx.iOS
    {
        public class ShellCustomRenderer : ShellRenderer
        {
            protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
            {
                return new TabBarAppearance();
            }
    
        }
    
        public class TabBarAppearance : IShellTabBarAppearanceTracker
        {
            public void Dispose()
            {
    
            }
    
            public void ResetAppearance(UITabBarController controller)
            {
                
    
            }
          
            public void SetAppearance(UITabBarController controller, ShellAppearance appearance)
            {
                UITabBar myTabBar = controller.TabBar;
    
                if (myTabBar.Items != null)
                {
                    var item = myTabBar.Items[0];
    
                    //default icon
                    item.Image = UIImage.FromBundle("xxx.png").ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
    
                    //selected icon
                    item.SelectedImage = UIImage.FromBundle("xxx.png").ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
                }
            }
    
            
    
            public void UpdateLayout(UITabBarController controller)
            {
            }
        }   
    
    }
    

    in Android

    [assembly: ExportRenderer(typeof(AppShell), typeof(ShellCustomRenderer ))]
    namespace xxx.Droid
    {
        public class ShellCustomRenderer : 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)
            {
                bottomView.ItemIconTintList = null;
                IMenu myMenu = bottomView.Menu;
    
                IMenuItem myItemOne = myMenu.GetItem(0);
    
                if (myItemOne.IsChecked)
                {
                    myItemOne.SetIcon(Resource.Drawable.xxx); // selected icon
                }
                else
                {
                    myItemOne.SetIcon(Resource.Drawable.xxx); //default icon
                }
    
             
    
            }
        }
    }