5.2-浮出控件导航Flyout-FlyoutItem/MenuItem/Header/Footer
如前章所述,Shell导航框架,在UI层面,有两种导航方式,一是浮出控件导航,二是底部Tab栏导航,本章节将深入学习浮出控件导航。浮出控件提供了非常丰富的定制功能,组成部分如下图所示:
一、Header/Footer页头和页尾设置(Header和Footer的使用方式一样)
1、通过DataTemplate设置
<Shell
......
Shell.FlyoutBehavior="Flyout">
<!--浮出框的页头-->
<Shell.FlyoutHeaderTemplate>
<DataTemplate>
<VerticalStackLayout>
<Label Text="这里是头部" />
<Image Aspect="Center" Source="dotnet_bot.png" />
</VerticalStackLayout>
</DataTemplate>
</Shell.FlyoutHeaderTemplate>
<!--浮出框的页尾-->
<Shell.FlyoutFooterTemplate>
<DataTemplate>
<VerticalStackLayout>
<Label Text="这里是尾部" />
<Image Aspect="Center" Source="dotnet_bot.png" />
</VerticalStackLayout>
</DataTemplate>
</Shell.FlyoutFooterTemplate>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
......
</FlyoutItem>
</Shell>
2、通过控件模板ContentView设置
<!--AppShell.xaml设置-->
<Shell ...>
<!--通过Shell.FlyoutHeader/Shell.FlyoutFooter设置-->
<Shell.FlyoutFooter>
<!--实例化控件模板-->
<controls:FlyoutFooter />
</Shell.FlyoutFooter>
</Shell>
<!--控件模板FlyoutFooter.xaml-->
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"
x:Class="Xaminals.Controls.FlyoutFooter">
<StackLayout>
<Label Text="这里是页头/页尾"/>
<Label Text="{Binding Source={x:Static sys:DateTime.Now}, StringFormat='{0:MMMM dd, yyyy}'}" />
</StackLayout>
</ContentView>
二、FlyoutItem浮出导航项设置
1、定义多个FlyoutItem、Title和Icon属性、隐式使用ShellContent
<!--定义多个FlyoutItem-->
<Shell ......>
<!--Title-项目标题,Icon-项目图标-->
<!--只有一个Tab,没有对应的底部Tab栏-->
<FlyoutItem Title="Cats" Icon="cat.png">
<Tab>
<ShellContent ContentTemplate="{DataTemplate views:CatsPage}" />
</Tab>
</FlyoutItem>
<FlyoutItem Title="Dogs" Icon="dog.png">
<Tab>
<ShellContent ContentTemplate="{DataTemplate views:DogsPage}" />
</Tab>
</FlyoutItem>
</Shell>
<!--以下结果和上面的一样-->
<!--Shell的默认内容属性为FlyoutItem,FlyoutItem的内容属性为Tab,Tab的内容属性为ShellContent-->
<!--根据XAML原理,默认内容的元素标签可以省略-->
<Shell ......>
<ShellContent ContentTemplate="{DataTemplate views:CatsPage}" />
<ShellContent ContentTemplate="{DataTemplate views:DogsPage}" />
</Shell>
2、FlyoutDisplayOptions设置,是否显示项目明细条目。
下图显示FlyoutDisplayOptions的设置效果,同时可以看出每个FlyoutItem都有一个对应的底部Tab栏
3、设置FlyoutItem外观方法①:内联DataTemplate。可以将Shell视为一个集合,ItemSource为浮出项,ItemTemplate为数据模板
<Shell
......>
<Shell.ItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="0.2*,0.8*">
<Image
Margin="5"
HeightRequest="45"
Source="{Binding FlyoutIcon}" />
<Label
Grid.Column="1"
FontAttributes="Italic"
Text="{Binding Title}"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
......
</FlyoutItem>
</Shell>
4、设置FlyoutItem外观方法②:资源字典DataTemplate。以下为默认的数据模板,可以定义到App.xaml资源字典中,并在此基础上进行修改。
<!--使用资源字典中的数据模板-->
<Shell
......
ItemTemplate="{StaticResource FlyoutTemplate}">
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
......
</FlyoutItem>
</Shell>
<!--可以将这个数据模板定义到App.xaml的资源字典中-->
<DataTemplate x:Key="FlyoutTemplate">
<Grid x:Name="FlyoutItemLayout"
HeightRequest="{OnPlatform 44, Android=50}"
ColumnSpacing="{OnPlatform WinUI=0}"
RowSpacing="{OnPlatform WinUI=0}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="Transparent" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="{AppThemeBinding Light=Black, Dark=White}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{OnPlatform Android=54, iOS=50, WinUI=Auto}" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image x:Name="FlyoutItemImage"
Source="{Binding FlyoutIcon}"
VerticalOptions="Center"
HorizontalOptions="{OnPlatform Default=Center, WinUI=Start}"
HeightRequest="{OnPlatform Android=24, iOS=22, WinUI=16}"
WidthRequest="{OnPlatform Android=24, iOS=22, WinUI=16}">
<Image.Margin>
<OnPlatform x:TypeArguments="Thickness">
<OnPlatform.Platforms>
<On Platform="WinUI"
Value="12,0,12,0" />
</OnPlatform.Platforms>
</OnPlatform>
</Image.Margin>
</Image>
<Label x:Name="FlyoutItemLabel"
Grid.Column="1"
Text="{Binding Title}"
FontSize="{OnPlatform Android=14, iOS=14}"
FontAttributes="{OnPlatform iOS=Bold}"
HorizontalOptions="{OnPlatform WinUI=Start}"
HorizontalTextAlignment="{OnPlatform WinUI=Start}"
VerticalTextAlignment="Center">
<Label.TextColor>
<OnPlatform x:TypeArguments="Color">
<OnPlatform.Platforms>
<On Platform="Android"
Value="{AppThemeBinding Light=Black, Dark=White}" />
</OnPlatform.Platforms>
</OnPlatform>
</Label.TextColor>
<Label.Margin>
<OnPlatform x:TypeArguments="Thickness">
<OnPlatform.Platforms>
<On Platform="Android"
Value="20, 0, 0, 0" />
</OnPlatform.Platforms>
</OnPlatform>
</Label.Margin>
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<OnPlatform.Platforms>
<On Platform="Android"
Value="sans-serif-medium" />
</OnPlatform.Platforms>
</OnPlatform>
</Label.FontFamily>
</Label>
</Grid>
</DataTemplate>
5、设置FlyoutItem外观方法③:绑定Shell的BindingContext,使用集合来完全定义
<!--方式①:Shell.FlyoutContent属性-->
<Shell ...
x:Name="shell">
...
<Shell.FlyoutContent>
<CollectionView BindingContext="{x:Reference shell}"
IsGrouped="True"
ItemsSource="{Binding FlyoutItems}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Title}"
TextColor="White"
FontSize="18" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Shell.FlyoutContent>
</Shell>
<!--方式②:Shell.FlyoutContentTemplate属性-->
<Shell ...
x:Name="shell">
...
<Shell.FlyoutContentTemplate>
<DataTemplate>
<CollectionView BindingContext="{x:Reference shell}"
IsGrouped="True"
ItemsSource="{Binding FlyoutItems}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Title}"
TextColor="White"
FontSize="18" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</DataTemplate>
</Shell.FlyoutContentTemplate>
</Shell>
三、MenuItem菜单导航项设置
<Shell
......>
<!--在FlyoutItem前显示-->
<MenuItem
Text="Help"
IconImageSource="help.png"
Command="{Binding HelpCommand}"
CommandParameter="https://learn.microsoft.com/dotnet/maui/fundamentals/shell"
/>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<Tab Title="Domestic">
<ShellContent Title="Cats" ContentTemplate="{DataTemplate view:Cats}" />
<ShellContent Title="Dogs" ContentTemplate="{DataTemplate view:Dogs}" />
</Tab>
<ShellContent Title="Monkeys" ContentTemplate="{DataTemplate view:Monkeys}" />
</FlyoutItem>
<!--在FlyoutItem后显示-->
<MenuItem
Text="About"
IconImageSource="about.png"
Command="{Binding AboutCommand}"
CommandParameter="https://learn.microsoft.com/dotnet/maui/fundamentals/shell"
/>
</Shell>
2、设置MenuItem外观的方法和FlyoutItem一样,略…
四、其它属性设置
<Shell
......
CurrentItem="{x:Reference about}" <!--指定首页-->
FlyoutIsPresented="True" <!--浮出框默认显示-->
FlyoutBehavior="Flyout" <!--浮出框是否显示,Flyout/Disabled/Locked-->
FlyoutVerticalScrollMode="Disabled" <!--垂直滚动,Disabled/Enabled/Auto-->
FlyoutIcon="dotnet_bot.png" <!--浮出框图标-->
FlyoutBackgroundColor="AliceBlue" <!--浮出框背景色-->
FlyoutBackgroundImage="dotnet_bot.png" <!--浮出框背景图-->
FlyoutBackgroundImageAspect="AspectFill" <!--浮出框背景图缩放方式-->
FlyoutWidth="200" <!--浮出框宽度-->
FlyoutHeight="400" <!--浮出框高度-->
>
<!-- 定义复杂的渐变浮出框背景① -->
<Shell.FlyoutBackground>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0.1" Color="#8A2387" />
<GradientStop Offset="0.6" Color="#E94057" />
<GradientStop Offset="1.0" Color="#F27121" />
</LinearGradientBrush>
</Shell.FlyoutBackground>
<!-- 定义复杂的渐变浮出框背景② -->
<Shell.FlyoutBackdrop>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0.1" Color="#8A2387" />
<GradientStop Offset="0.6" Color="#E94057" />
<GradientStop Offset="1.0" Color="#F27121" />
</LinearGradientBrush>
</Shell.FlyoutBackdrop>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
......
<ShellContent
x:Name="about"
Title="About"
ContentTemplate="{DataTemplate view:About}"/>
</FlyoutItem>
</Shell>