Android MAUI中如何正确创建并导航至带双标签的TabbedPage?
问题描述
开发的.NET MAUI应用包含两个页面:主页为非TabbedPage,设有按钮用于导航至第二个页面——带有两个子页面的TabbedPage配置页。配置页的第一个标签页用于设置用户数据,第二个标签页用于配置其他设置。点击主页按钮导航至配置页时,出现如下异常:
'No view found for id 0x7f080144 (com.companyname.navigatetotabbedpage:id/navigationlayout_toptabs) for fragment ViewFragment{bfd0a32} (bac519b5-33dc-483e-8124-aff189fabf28 id=0x7f080144)'
应用代码
AppShell.xaml
<?xml version="1.0" encoding="UTF-8" ?> <Shell x:Class="NavigateToTabbedPage.AppShell" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:NavigateToTabbedPage.Views" Shell.FlyoutBehavior="Disabled"> <ShellContent Title="Home" ContentTemplate="{DataTemplate local:MainView}" Route="MainPage" /> </Shell>
AppShell.xaml.cs
using NavigateToTabbedPage.Views; namespace NavigateToTabbedPage; public partial class AppShell : Shell { public AppShell() { InitializeComponent(); Routing.RegisterRoute(nameof(GeneralConfigurationView), typeof(GeneralConfigurationView)); } }
MainView.xaml
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NavigateToTabbedPage.Views.MainView" Title="MainView"> <VerticalStackLayout> <Button Text="Configuration" Clicked="Button_Clicked"/> </VerticalStackLayout> </ContentPage>
MainView.xaml.cs
namespace NavigateToTabbedPage.Views; public partial class MainView : ContentPage { public MainView() { InitializeComponent(); } private void Button_Clicked(object sender, EventArgs e) { Shell.Current.GoToAsync(nameof(GeneralConfigurationView)); } }
GeneralConfigurationView.xaml
<?xml version="1.0" encoding="utf-8" ?> <TabbedPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NavigateToTabbedPage.Views.GeneralConfigurationView" xmlns:local="clr-namespace:NavigateToTabbedPage.Views" Title="GeneralConfigurationView"> <local:UserConfigurationView/> <local:OtherSettingsConfigurationView/> </TabbedPage>
UserConfigurationView.xaml
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NavigateToTabbedPage.Views.UserConfigurationView" Title="UserConfigurationView"> <VerticalStackLayout> <Label Text="Welcome to .NET MAUI!" VerticalOptions="Center" HorizontalOptions="Center" /> </VerticalStackLayout> </ContentPage>
OtherSettingsConfigurationView.xaml
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NavigateToTabbedPage.Views.OtherSettingsConfigurationView" Title="OtherSettingsConfigurationView"> <VerticalStackLayout> <Label Text="Welcome to .NET MAUI!" VerticalOptions="Center" HorizontalOptions="Center" /> </VerticalStackLayout> </ContentPage>
解决方案
这个异常的核心原因是在Shell导航体系中直接导航到TabbedPage会出现布局冲突,因为Shell本身有自己的导航结构,TabbedPage作为传统页面容器,和Shell的导航栈兼容存在问题。提供两种可行解决方法:
方法一:改用Shell的TabBar替代传统TabbedPage
完全遵循Shell导航规范,用Shell原生的TabBar结构实现标签页功能:
- 修改AppShell.xaml,添加TabBar并配置路由:
<?xml version="1.0" encoding="UTF-8" ?> <Shell x:Class="NavigateToTabbedPage.AppShell" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:NavigateToTabbedPage.Views" Shell.FlyoutBehavior="Disabled"> <!-- 主页 --> <ShellContent Title="Home" ContentTemplate="{DataTemplate local:MainView}" Route="MainPage" /> <!-- 配置页的TabBar --> <TabBar Route="GeneralConfiguration"> <ShellContent Title="用户配置" ContentTemplate="{DataTemplate local:UserConfigurationView}" Route="UserConfig"/> <ShellContent Title="其他设置" ContentTemplate="{DataTemplate local:OtherSettingsConfigurationView}" Route="OtherSettings"/> </TabBar> </Shell>
- 调整AppShell.xaml.cs的路由注册:
using NavigateToTabbedPage.Views; namespace NavigateToTabbedPage; public partial class AppShell : Shell { public AppShell() { InitializeComponent(); // 注册到配置TabBar的路由 Routing.RegisterRoute("GeneralConfiguration", typeof(Shell)); // 可选:注册到具体标签页的路由 Routing.RegisterRoute("GeneralConfiguration/UserConfig", typeof(UserConfigurationView)); } }
- 修改MainView的导航代码:
private void Button_Clicked(object sender, EventArgs e) { // 导航到配置TabBar的根路由 Shell.Current.GoToAsync("//GeneralConfiguration"); }
方法二:用NavigationPage包裹TabbedPage再导航
如果坚持使用传统TabbedPage,需要将其包裹在NavigationPage中,避免和Shell导航结构冲突:
- 修改MainView的导航代码:
private async void Button_Clicked(object sender, EventArgs e) { await Navigation.PushAsync(new NavigationPage(new GeneralConfigurationView())); }
- 移除AppShell中对GeneralConfigurationView的路由注册:
public AppShell() { InitializeComponent(); // 移除原有路由注册代码 }
注意事项
- 优先推荐方法一,Shell是.NET MAUI官方推荐的导航框架,能更好适配多平台导航体验与生命周期管理。
- 方法二属于兼容传统页面的临时方案,在Shell体系下可能出现导航栏样式不一致等问题。
内容的提问来源于stack exchange,提问作者Álvaro García
相关产品推荐
相关产品推荐

