.NET Maui中如何修改TabbedPage的标签栏样式?
.NET Maui TabbedPage 自定义底部标签栏样式方案
你当前的TabbedPage代码如下:
<TabbedPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="AppTesting.TabPage" xmlns:local="clr-namespace:AppTesting.Pages" xmlns:android="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.AndroidSpecific;assembly=Microsoft.Maui.Controls" android:TabbedPage.ToolbarPlacement="Bottom" BarBackgroundColor="#1d1f20" Title="Ta" > <local:HomePage Title="Home"/> <local:Account Title="Account"/> </TabbedPage>
要修改成目标样式(深色底部背景、选中标签高亮、图标+文字组合、底部选中指示器),可以用以下两种方案:
方案一:自定义ControlTemplate(跨平台通用)
通过自定义ControlTemplate可完全控制标签栏的布局和样式,实现跨平台统一效果。
步骤1:添加ControlTemplate到TabbedPage资源中
在你的TabPage.xaml里添加资源字典,定义自定义模板和样式:
<TabbedPage.Resources> <ResourceDictionary> <!-- 自定义TabbedPage模板 --> <ControlTemplate x:Key="CustomTabbedPageTemplate"> <Grid> <!-- 承载当前页面内容 --> <ContentPresenter Content="{TemplateBinding CurrentPage}" /> <!-- 底部标签栏容器 --> <Grid VerticalOptions="End" BackgroundColor="#1d1f20" HeightRequest="60"> <!-- 标签项横向布局 --> <HorizontalStackLayout HorizontalOptions="CenterAndExpand" Spacing="40"> <!-- 首页标签 --> <ContentView Padding="10,5" GestureRecognizers="{TapGestureRecognizer Command={Binding Source={RelativeSource TemplatedParent}, Path=SelectTabCommand}, CommandParameter=0}"> <ContentView.Triggers> <DataTrigger TargetType="ContentView" Binding="{Binding Source={RelativeSource TemplatedParent}, Path=SelectedIndex}" Value="0"> <Setter Property="Style" Value="{StaticResource SelectedTabStyle}" /> </DataTrigger> <DataTrigger TargetType="ContentView" Binding="{Binding Source={RelativeSource TemplatedParent}, Path=SelectedIndex}" Value="1"> <Setter Property="Style" Value="{StaticResource UnselectedTabStyle}" /> </DataTrigger> </ContentView.Triggers> <VerticalStackLayout HorizontalOptions="Center"> <Image Source="home_icon" WidthRequest="24" HeightRequest="24" /> <Label Text="Home" FontSize="12" /> </VerticalStackLayout> </ContentView> <!-- 账户标签 --> <ContentView Padding="10,5" GestureRecognizers="{TapGestureRecognizer Command={Binding Source={RelativeSource TemplatedParent}, Path=SelectTabCommand}, CommandParameter=1}"> <ContentView.Triggers> <DataTrigger TargetType="ContentView" Binding="{Binding Source={RelativeSource TemplatedParent}, Path=SelectedIndex}" Value="1"> <Setter Property="Style" Value="{StaticResource SelectedTabStyle}" /> </DataTrigger> <DataTrigger TargetType="ContentView" Binding="{Binding Source={RelativeSource TemplatedParent}, Path=SelectedIndex}" Value="0"> <Setter Property="Style" Value="{StaticResource UnselectedTabStyle}" /> </DataTrigger> </ContentView.Triggers> <VerticalStackLayout HorizontalOptions="Center"> <Image Source="account_icon" WidthRequest="24" HeightRequest="24" /> <Label Text="Account" FontSize="12" /> </VerticalStackLayout> </ContentView> </HorizontalStackLayout> <!-- 选中状态底部指示器 --> <BoxView HeightRequest="2" BackgroundColor="#007AFF" VerticalOptions="End" WidthRequest="60" HorizontalOptions="Start"> <BoxView.Triggers> <DataTrigger TargetType="BoxView" Binding="{Binding Source={RelativeSource TemplatedParent}, Path=SelectedIndex}" Value="0"> <Setter Property="TranslationX" Value="45" /> </DataTrigger> <DataTrigger TargetType="BoxView" Binding="{Binding Source={RelativeSource TemplatedParent}, Path=SelectedIndex}" Value="1"> <Setter Property="TranslationX" Value="145" /> </DataTrigger> </BoxView.Triggers> </BoxView> </Grid> </Grid> </ControlTemplate> <!-- 标签选中/未选中样式 --> <Style x:Key="SelectedTabStyle" TargetType="ContentView"> <Setter Property="Label.TextColor" Value="#007AFF" /> <Setter Property="Image.TintColor" Value="#007AFF" /> </Style> <Style x:Key="UnselectedTabStyle" TargetType="ContentView"> <Setter Property="Label.TextColor" Value="#888888" /> <Setter Property="Image.TintColor" Value="#888888" /> </Style> </ResourceDictionary> </TabbedPage.Resources>
步骤2:给TabbedPage应用自定义模板
修改TabbedPage的ControlTemplate属性,移除原有的Android平台相关属性:
<TabbedPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="AppTesting.TabPage" xmlns:local="clr-namespace:AppTesting.Pages" ControlTemplate="{StaticResource CustomTabbedPageTemplate}" Title="Ta" > <local:HomePage Title="Home"/> <local:Account Title="Account"/> </TabbedPage>
注意事项
- 替换
home_icon和account_icon为你项目中实际的图标资源(确保已添加到资源文件中) - 调整
BoxView的TranslationX值,让选中指示器对齐对应标签 - 可根据需求修改背景色、文字大小、图标尺寸、间距等参数
方案二:Android平台自定义Handler(原生适配)
如果只需要适配Android平台,可通过自定义Handler修改原生TabLayout的样式,更贴近原生效果。
步骤1:创建自定义TabbedPageHandler
在Platforms/Android/Handlers目录下创建CustomTabbedPageHandler.cs:
using Android.Views; using AndroidX.ViewPager.Widget; using Microsoft.Maui.Platform; using Google.Android.Material.Tabs; namespace AppTesting.Platforms.Android.Handlers; public class CustomTabbedPageHandler : TabbedViewHandler { protected override void ConnectHandler(MauiTabbedView platformView) { base.ConnectHandler(platformView); if (platformView.ViewPager == null) return; var tabLayout = platformView.TabLayout; if (tabLayout == null) return; // 设置标签栏背景色 tabLayout.SetBackgroundColor(Android.Graphics.Color.ParseColor("#1d1f20")); // 定义选中/未选中的颜色状态列表 var colorStateList = new Android.Graphics.ColorStateList( new int[][] { new int[] { Android.Resource.Attribute.StateSelected }, new int[] { } }, new int[] { Android.Graphics.Color.ParseColor("#007AFF"), // 选中颜色 Android.Graphics.Color.ParseColor("#888888") // 未选中颜色 }); // 应用颜色到文字和图标 tabLayout.SetTabTextColors(colorStateList); tabLayout.SetIconTint(colorStateList); // 设置选中指示器样式 tabLayout.SetSelectedTabIndicatorColor(Android.Graphics.Color.ParseColor("#007AFF")); tabLayout.SetSelectedTabIndicatorHeight(2); // 调整标签布局为图标在上、文字在下 for (int i = 0; i < tabLayout.TabCount; i++) { var tab = tabLayout.GetTabAt(i); if (tab == null) continue; tab.SetCustomView(CreateTabLayout(tab.Text, tab.Icon)); } } // 创建自定义标签布局 private View CreateTabLayout(string text, Android.Graphics.Drawables.Drawable icon) { var layout = new LinearLayout(Context) { Orientation = Orientation.Vertical, Gravity = GravityFlags.Center }; var imageView = new ImageView(Context) { LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent) { BottomMargin = 4 }, ImageDrawable = icon }; var textView = new TextView(Context) { Text = text, TextSize = 12, LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent) }; layout.AddView(imageView); layout.AddView(textView); return layout; } }
步骤2:注册自定义Handler
在MauiProgram.cs中注册该Handler:
builder.ConfigureMauiHandlers(handlers => { #if ANDROID handlers.AddHandler(typeof(TabbedPage), typeof(AppTesting.Platforms.Android.Handlers.CustomTabbedPageHandler)); #endif });
内容的提问来源于stack exchange,提问作者BeginnerWPF
相关产品推荐
相关产品推荐

