2

I'm using Xamarin Forms Shell. How can you change the color of icons in the flyout menu when using tabs?

For example I'm using a png of a black icon as my tab icon.

<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
    <Tab Icon="pie_chart.png"
         Title="Daily Target">
        <ShellContent Route="TargetDataPage" ContentTemplate="{DataTemplate targetDataPageView:TargetDataPageView}" />
    </Tab>
    ...
</FlyoutItem>

Setting the Shell TabBarTitleColor value changes the color of the black png to white in the tabs. (Which is good)

<Shell.Resources>
<ResourceDictionary>
    <Style x:Key="BaseStyle" TargetType="Element">
        ...                
        <Setter Property="Shell.TabBarTitleColor" Value="White"/>
        <Setter Property="Shell.TabBarUnselectedColor" Value="#95FFFFFF"/>
    </Style>
    <Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
    <Style TargetType="FlyoutItem" BasedOn="{StaticResource BaseStyle}" />
    </ResourceDictionary>
</Shell.Resources>

Is there a setter to set the color of the icon in the flyout menu? I need to set this because black is no good in dark mode, but I can't swap the icon for a white png icon because it's then the wrong color in light mode.

If there isn't a specific setter for flyout menu icon color, how else can I set the color? Bearing in mind the icon is set in the tab.

ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196
  • Does this answer your question? [Xamarin Forms: How Can I Change the FlyoutItem.Icon's Color When It Is Selected/Deselected?](https://stackoverflow.com/questions/65400688/xamarin-forms-how-can-i-change-the-flyoutitem-icons-color-when-it-is-selected) – ToolmakerSteve Nov 30 '21 at 00:43
  • Thanks @ToolmakerSteve I've tried it and while it works with ordinary flyout items, it doesn't work with tabs. – c0ff33-b34n Nov 30 '21 at 15:40

2 Answers2

0

1.Create a custom flyout with an additional IconGlyphProperty in folder Controls

namespace Xaminals.Controls
 {
     public class FlyoutItemIconFont: FlyoutItem
     {
         public static readonly BindableProperty IconGlyphProperty = BindableProperty.Create(nameof(IconGlyphProperty), typeof(string), typeof(FlyoutItemIconFont), string.Empty);
         public string IconGlyph
         {
             get { return (string)GetValue(IconGlyphProperty); }
             set { SetValue(IconGlyphProperty, value); }
         }
     }
 }

2.Create a FlyoutItemTemplate with two Lables and VisualStateManager:

 <Shell.ItemTemplate>
     <DataTemplate>
         <Grid>
             <VisualStateManager.VisualStateGroups>
                 <VisualStateGroupList>
                     <VisualStateGroup x:Name="CommonStates">
                         <VisualState x:Name="Normal">
                             <VisualState.Setters>
                                 <Setter Property="BackgroundColor" Value="White" />
                                     <Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource Primary}" />
                             </VisualState.Setters>
                         </VisualState>
                         <VisualState x:Name="Selected">
                             <VisualState.Setters>
                                     <Setter Property="BackgroundColor" Value="{StaticResource Primary}" />
                                 <Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="White" />
                             </VisualState.Setters>
                         </VisualState>
                     </VisualStateGroup>
                 </VisualStateGroupList>
             </VisualStateManager.VisualStateGroups>
    
             <Grid.ColumnDefinitions>
                 <ColumnDefinition Width="0.2*" />
                 <ColumnDefinition Width="0.8*" />
             </Grid.ColumnDefinitions>
             <Label x:Name="FlyoutItemIcon"
                 FontFamily="MaterialDesignFont"       
                 Text="{Binding IconGlyph}"
                 TextColor="{Binding Source={x:Reference FlyoutItemLabel} ,Path=TextColor}"
                 FontSize="30"
                 Margin="5"/>
             <Label x:Name="FlyoutItemLabel"
                 Grid.Column="1"        
                 Text="{Binding Title}"
                 VerticalTextAlignment="Center" />
         </Grid>
     </DataTemplate>
 </Shell.ItemTemplate> 

3.Replace the original FlyoutItem in AppShell.xaml with the custom FlyoutItem

<controls:FlyoutItemIconFont Title="About" IconGlyph="{StaticResource IconInfo}">
     <ShellContent Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
 </controls:FlyoutItemIconFont>
    
 <controls:FlyoutItemIconFont Title="Browse" IconGlyph="{StaticResource IconListBulleted}">
     <ShellContent Route="ItemsPage" ContentTemplate="{DataTemplate local:ItemsPage}" />
 </controls:FlyoutItemIconFont>

4.And add the BaseStyle to the customFlyouItem

<!--other style-->
     <x:String x:Key="IconInfo">&#xF02FD;</x:String>
     <x:String x:Key="IconListBulleted">&#xF0279;</x:String>
     <Style TargetType="controls:FlyoutItemIconFont" BasedOn="{StaticResource BaseStyle}"/>

Result enter image description here

Refer to this - Xamarin Forms: How Can I Change the FlyoutItem.Icon's Color When It Is Selected/Deselected?

logeshpalani31
  • 1,416
  • 12
  • 33
  • This is the only possible workaround , we have to use Material icon , since its color could change when something triggers(like dark/light mode, selected/unselected). – ColeX Nov 30 '21 at 07:21
  • I'm using Tabs to specify the image. How does that fit in with step 3? – c0ff33-b34n Nov 30 '21 at 11:10
0
  1. Followed the case i done before with the Material Design Icons. Xamarin Forms: How Can I Change the FlyoutItem.Icon's Color When It Is Selected/Deselected?

    <Shell.Resources>
     <ResourceDictionary>
         <Color x:Key="fgColor">#66169C</Color>
         <Color x:Key="bgColor">#FFFFFF</Color>
         <Color x:Key="OverDueItem">#FF1C07</Color>
    
         <OnPlatform x:Key="Material" x:TypeArguments="x:String">
             <On Platform="iOS" Value="Material Design Icons" />
             <On Platform="Android" Value="materialdesignicons-webfont.ttf#Material Design Icons" />
         </OnPlatform>
         <Style x:Key="MaterialIcons" TargetType="{x:Type Label}">
             <Setter Property="FontFamily" Value="{DynamicResource Material}" />
             <Setter Property="FontSize" Value="100" />
             <Setter Property="HorizontalOptions" Value="Center" />
             <Setter Property="VerticalOptions" Value="Center" />
             <Setter Property="TextColor" Value="{DynamicResource fgColor}" />
             <Setter Property="FontSize" Value="Large" />
         </Style>
         <Style x:Key="FloutItemStyle" TargetType="Grid">
             <Setter Property="VisualStateManager.VisualStateGroups">
                 <VisualStateGroupList>
                     <VisualStateGroup x:Name="CommonStates">
                         <VisualState x:Name="Normal" />
                         <VisualState x:Name="Selected">
                             <VisualState.Setters>
                                 <Setter Property="BackgroundColor" Value="Accent" />
    
                             </VisualState.Setters>
                         </VisualState>
                     </VisualStateGroup>
                 </VisualStateGroupList>
             </Setter>
         </Style>
     </ResourceDictionary>
    </Shell.Resources>
    
  2. When you use the tab inside FlyoutItem, you could set the Material Design Icons using FontImageSource.

    <FlyoutItem FlyoutDisplayOptions="AsMultipleItems" >
    
     <Tab Title="Page1" >
         <Tab.FlyoutIcon>
             <FontImageSource FontFamily="{StaticResource Material}" Color="{DynamicResource fgColor}" Glyph="&#xf001;">
             </FontImageSource>
         </Tab.FlyoutIcon>
         <Tab.Icon>
             <FontImageSource FontFamily="{StaticResource Material}" Color="{DynamicResource fgColor}" Glyph="&#xf001;" >
             </FontImageSource>
         </Tab.Icon>
         <ShellContent Route="Page1" ContentTemplate="{DataTemplate local:Page1}" />
     </Tab>
     <Tab Title="Page2">
         <Tab.FlyoutIcon>
             <FontImageSource FontFamily="{StaticResource Material}" Color="{DynamicResource fgColor}" Glyph="&#xf001;">
             </FontImageSource>
         </Tab.FlyoutIcon>
         <Tab.Icon>
             <FontImageSource FontFamily="{StaticResource Material}" Color="{DynamicResource fgColor}" Glyph="&#xf001;" >
             </FontImageSource>
         </Tab.Icon>
         <ShellContent Route="Page2" ContentTemplate="{DataTemplate local:Page2}"/>
     </Tab>
     </FlyoutItem>
    
  3. Change the ItemTemplate of the FlyoutItem. Use the Label to set the Material Design Icons instead of Image. You could change the color when you select via Triggers to change the TextColor.

    <Shell.ItemTemplate>
     <DataTemplate>
         <Grid x:Name="grid" Style="{StaticResource FloutItemStyle}">
    
             <Grid.ColumnDefinitions>
                 <ColumnDefinition Width="0.2*" />
                 <ColumnDefinition Width="0.8*" />
             </Grid.ColumnDefinitions>
             <Label Style="{StaticResource MaterialIcons}" Text="{Binding FlyoutIcon.Glyph}" 
                    Margin="5" 
                    HeightRequest="45">
                 <Label.Triggers>
                     <DataTrigger
                     Binding="{Binding Source={x:Reference grid}, Path=BackgroundColor}"
                     TargetType="Label" Value="Accent">
                         <Setter Property="TextColor" Value="White" />
                     </DataTrigger>
                 </Label.Triggers>
             </Label>
             <Label Grid.Column="1"
                    Text="{Binding Title}"
                    FontAttributes="Italic"
                    VerticalTextAlignment="Center" />
         </Grid>
     </DataTemplate>
     </Shell.ItemTemplate>
    
Wendy Zang - MSFT
  • 10,509
  • 1
  • 7
  • 17