Xamarin.Forms:如何在AppShell中设置FlyoutItems中图标的颜色
Xamarin.Forms: How to set the Color of Icons in FlyoutItems in AppShell
我正在使用 AppShell 实现一个 Xamarin.Forms 应用程序,但似乎无法弄清楚如何在 Flyout 菜单中设置选定/未选定图标的颜色。这是我认为控制行为的 appshell.xaml 部分(我使用各种高对比度颜色来显示哪些设置控制了什么)。 (完整代码示例:https://github.com/wadebaird/ShellExample 供更多参考):
<Style x:Name="FlyoutItem" Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<!-- This is the color of the unselected text for the labels in the flyout-->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Magenta" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="Cyan" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter Property="BackgroundColor" Value="Green" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<!-- This is the color of the selected text in the flyout -->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Black"/>
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="Yellow" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter Property="BackgroundColor" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
这是这些设置的视觉效果。在此图像中,“顶部的实体是”选定的“项目。我希望/希望图标与文本的颜色相匹配,但似乎找不到设置。
以下是我要展示的图标“白色”是如何不起作用的:
我可以在 FontImageSource 上手动设置颜色,但它总是那个颜色,并且与选定/未选定的颜色不匹配:
<ShellContent Route="aboutPage" Title="About" ContentTemplate="{DataTemplate views:AboutPage}" >
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Color="Black" Glyph="{x:Static fontAwesome:FontAwesomeIcons.InfoCircle}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
我在“普通状态”-“正常”/“已选择”中尝试了各种类似的东西,但没有任何效果。:
<Setter Property="FontImageSource.Color" Value="{AppThemeBinding Light={StaticResource PrimaryUnselectedTextColorLight}, Dark={StaticResource PrimaryUnselectedTextColorDark}}" />
附带说明(这可能是一个错误)。在 iOS 上显示,当第一次打开弹出窗口时,没有任何内容被“选中”:
在 Android 上,选择了正确的项目:
我知道这是一个单独的项目,如果我找不到现有的 issue/bug,我会记录一个错误,但我想我会提到它,因为有人知道我的答案上面可能已经意识到这个问题了。
您可以使用Shell.ItemTemplate
设置标签和图标的背景颜色。并使用 VisualStateGroup
更改选中状态的颜色。
Shell.ItemTemplate:
<Shell.ItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="0.2*,0.8*" ColumnSpacing="0" Style="{StaticResource FloutItemStyle}">
<Image x:Name="FlyoutItemIcon" Source="{Binding FlyoutIcon}" HeightRequest="45" />
<Label x:Name="FlyoutItemLabel" Grid.Column="1"
Text="{Binding Title}"
FontAttributes="Italic"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
风格:
<Style x:Key="FloutItemStyle" Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{x:OnPlatform UWP=Transparent, iOS=White}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource Primary}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="Blue" />
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="Green" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource Primary}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="{StaticResource Primary}" />
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="{StaticResource Primary}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
在 Wendy Zang 的部分解决方案之后(它解决了背景颜色但没有解决前景),它让我走上了正确的轨道
我能够找到 , which utilized two labels instead of an image. (I also tried to use the Image that Wendy suggested above and an effect like the IconTintColorEffect.TintColor
from this ,但我无法让它正常工作,因为图标的大小对于图像来说要复杂得多。)
我尝试了将不同类型的派生 classes 与 IconGlyph 属性 搭配使用的解决方案,我让它运行良好,但我不喜欢它的简洁性。然后我想到使用 IValueConverter 来修复标签 class:
的绑定
public class FlyoutGlyphConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return null;
if (value is not BaseShellItem baseShellItem)
throw new ArgumentException($"This converter may only be used on values of type {nameof(BaseShellItem)}.");
if (baseShellItem.Icon is not FontImageSource fontImageSource)
throw new ArgumentException($"This converter may only be used on values of type {nameof(BaseShellItem)}s with Icons of type {nameof(FontImageSource)}.");
return fontImageSource.Glyph;
}
}
而我的 xaml 结果是这样的:
<Shell.ItemTemplate>
<DataTemplate x:DataType="root:IShellIconFont">
<Grid Margin="0" Padding="0" ColumnSpacing="0">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<!-- This is the color of the unselected text for the labels in the flyout-->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="#2196F3" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="White" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="White" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<!-- This is the color of the selected text in the flyout -->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="White"/>
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="#2196F3" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="#2196F3" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Label x:Name="FlyoutItemIcon" Grid.Column="0" FontFamily="FA-Solid" FontSize="{StaticResource FlyoutIconSize}"
Text="{Binding ., Converter={StaticResource FlyoutGlyph}}" TextColor="{Binding Source={x:Reference FlyoutItemLabel}, Path=TextColor}"
VerticalTextAlignment="Center" HorizontalTextAlignment="Center"
Margin="0" Padding="0"/>
<Label x:Name="FlyoutItemLabel" Grid.Column="1" Text="{Binding Title}" FontSize="{StaticResource FlyoutLabelFontSize}"
FontAttributes="Bold" VerticalTextAlignment="Center" HeightRequest="45" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
<FlyoutItem Route="root" Title="Entitys" FlyoutDisplayOptions="AsMultipleItems">
<root:ShellContentIconFont Route="mainPage" Title="Entity" Glyph="{x:Static fontAwesome:FontAwesomeIcons.BookOpen}" ContentTemplate="{DataTemplate views:MainPage}" />
<root:ShellContentIconFont Route="favoritesPage" Title="Favorites" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Star}" ContentTemplate="{DataTemplate views:FavoritesPage}" />
<root:TabIconFont Route="entitys" Title="Entitys" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Book}" >
<ShellContent Route="entitysCalendar" Title="Calendar" ContentTemplate="{DataTemplate views:EntitysCalendarPage}" />
<ShellContent Route="entitysList" Title="List" ContentTemplate="{DataTemplate views:EntitysListPage}" />
</root:TabIconFont>
</FlyoutItem>
<FlyoutItem Route="root" Title="Entitys" FlyoutDisplayOptions="AsMultipleItems">
<ShellContent Route="mainPage" Title="Entity" ContentTemplate="{DataTemplate views:MainPage}">
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.BookOpen}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
<ShellContent Route="favoritesPage" Title="Favorites" ContentTemplate="{DataTemplate views:FavoritesPage}">
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Star}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
<Tab Route="entitys" Title="Entitys">
<Tab.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Book}" FontFamily="FA-Solid" />
</Tab.Icon>
<ShellContent Route="entitysCalendar" Title="Calendar" ContentTemplate="{DataTemplate views:EntitysCalendarPage}" />
<ShellContent Route="entitysList" Title="List" ContentTemplate="{DataTemplate views:EntitysListPage}" />
</Tab>
</FlyoutItem>
<ShellContent Route="aboutPage" Title="About" ContentTemplate="{DataTemplate views:AboutPage}" >
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.InfoCircle}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
这是最终结果:
另一方面,此解决方案中的某些内容修复了 iOS 问题,即在初始打开时未选择任何内容。我猜这是定义的 DataTemplate。
我正在使用 AppShell 实现一个 Xamarin.Forms 应用程序,但似乎无法弄清楚如何在 Flyout 菜单中设置选定/未选定图标的颜色。这是我认为控制行为的 appshell.xaml 部分(我使用各种高对比度颜色来显示哪些设置控制了什么)。 (完整代码示例:https://github.com/wadebaird/ShellExample 供更多参考):
<Style x:Name="FlyoutItem" Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<!-- This is the color of the unselected text for the labels in the flyout-->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Magenta" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="Cyan" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter Property="BackgroundColor" Value="Green" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<!-- This is the color of the selected text in the flyout -->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Black"/>
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="Yellow" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter Property="BackgroundColor" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
这是这些设置的视觉效果。在此图像中,“顶部的实体是”选定的“项目。我希望/希望图标与文本的颜色相匹配,但似乎找不到设置。
以下是我要展示的图标“白色”是如何不起作用的:
我可以在 FontImageSource 上手动设置颜色,但它总是那个颜色,并且与选定/未选定的颜色不匹配:
<ShellContent Route="aboutPage" Title="About" ContentTemplate="{DataTemplate views:AboutPage}" >
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Color="Black" Glyph="{x:Static fontAwesome:FontAwesomeIcons.InfoCircle}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
我在“普通状态”-“正常”/“已选择”中尝试了各种类似的东西,但没有任何效果。:
<Setter Property="FontImageSource.Color" Value="{AppThemeBinding Light={StaticResource PrimaryUnselectedTextColorLight}, Dark={StaticResource PrimaryUnselectedTextColorDark}}" />
附带说明(这可能是一个错误)。在 iOS 上显示,当第一次打开弹出窗口时,没有任何内容被“选中”:
在 Android 上,选择了正确的项目:
我知道这是一个单独的项目,如果我找不到现有的 issue/bug,我会记录一个错误,但我想我会提到它,因为有人知道我的答案上面可能已经意识到这个问题了。
您可以使用Shell.ItemTemplate
设置标签和图标的背景颜色。并使用 VisualStateGroup
更改选中状态的颜色。
Shell.ItemTemplate:
<Shell.ItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="0.2*,0.8*" ColumnSpacing="0" Style="{StaticResource FloutItemStyle}">
<Image x:Name="FlyoutItemIcon" Source="{Binding FlyoutIcon}" HeightRequest="45" />
<Label x:Name="FlyoutItemLabel" Grid.Column="1"
Text="{Binding Title}"
FontAttributes="Italic"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
风格:
<Style x:Key="FloutItemStyle" Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{x:OnPlatform UWP=Transparent, iOS=White}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource Primary}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="Blue" />
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="Green" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource Primary}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="{StaticResource Primary}" />
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="{StaticResource Primary}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
在 Wendy Zang IconTintColorEffect.TintColor
from this
我尝试了将不同类型的派生 classes 与 IconGlyph 属性 搭配使用的解决方案,我让它运行良好,但我不喜欢它的简洁性。然后我想到使用 IValueConverter 来修复标签 class:
的绑定public class FlyoutGlyphConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return null;
if (value is not BaseShellItem baseShellItem)
throw new ArgumentException($"This converter may only be used on values of type {nameof(BaseShellItem)}.");
if (baseShellItem.Icon is not FontImageSource fontImageSource)
throw new ArgumentException($"This converter may only be used on values of type {nameof(BaseShellItem)}s with Icons of type {nameof(FontImageSource)}.");
return fontImageSource.Glyph;
}
}
而我的 xaml 结果是这样的:
<Shell.ItemTemplate>
<DataTemplate x:DataType="root:IShellIconFont">
<Grid Margin="0" Padding="0" ColumnSpacing="0">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<!-- This is the color of the unselected text for the labels in the flyout-->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="#2196F3" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="White" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="White" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<!-- This is the color of the selected text in the flyout -->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="White"/>
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="#2196F3" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="#2196F3" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Label x:Name="FlyoutItemIcon" Grid.Column="0" FontFamily="FA-Solid" FontSize="{StaticResource FlyoutIconSize}"
Text="{Binding ., Converter={StaticResource FlyoutGlyph}}" TextColor="{Binding Source={x:Reference FlyoutItemLabel}, Path=TextColor}"
VerticalTextAlignment="Center" HorizontalTextAlignment="Center"
Margin="0" Padding="0"/>
<Label x:Name="FlyoutItemLabel" Grid.Column="1" Text="{Binding Title}" FontSize="{StaticResource FlyoutLabelFontSize}"
FontAttributes="Bold" VerticalTextAlignment="Center" HeightRequest="45" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
<FlyoutItem Route="root" Title="Entitys" FlyoutDisplayOptions="AsMultipleItems">
<root:ShellContentIconFont Route="mainPage" Title="Entity" Glyph="{x:Static fontAwesome:FontAwesomeIcons.BookOpen}" ContentTemplate="{DataTemplate views:MainPage}" />
<root:ShellContentIconFont Route="favoritesPage" Title="Favorites" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Star}" ContentTemplate="{DataTemplate views:FavoritesPage}" />
<root:TabIconFont Route="entitys" Title="Entitys" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Book}" >
<ShellContent Route="entitysCalendar" Title="Calendar" ContentTemplate="{DataTemplate views:EntitysCalendarPage}" />
<ShellContent Route="entitysList" Title="List" ContentTemplate="{DataTemplate views:EntitysListPage}" />
</root:TabIconFont>
</FlyoutItem>
<FlyoutItem Route="root" Title="Entitys" FlyoutDisplayOptions="AsMultipleItems">
<ShellContent Route="mainPage" Title="Entity" ContentTemplate="{DataTemplate views:MainPage}">
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.BookOpen}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
<ShellContent Route="favoritesPage" Title="Favorites" ContentTemplate="{DataTemplate views:FavoritesPage}">
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Star}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
<Tab Route="entitys" Title="Entitys">
<Tab.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Book}" FontFamily="FA-Solid" />
</Tab.Icon>
<ShellContent Route="entitysCalendar" Title="Calendar" ContentTemplate="{DataTemplate views:EntitysCalendarPage}" />
<ShellContent Route="entitysList" Title="List" ContentTemplate="{DataTemplate views:EntitysListPage}" />
</Tab>
</FlyoutItem>
<ShellContent Route="aboutPage" Title="About" ContentTemplate="{DataTemplate views:AboutPage}" >
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.InfoCircle}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
这是最终结果:
另一方面,此解决方案中的某些内容修复了 iOS 问题,即在初始打开时未选择任何内容。我猜这是定义的 DataTemplate。