MAUI中TabbedPage导航报错:No view found for id异常
Maui导航至TabbedPage时触发Java.Lang.IllegalArgumentException的解决方案
问题背景
最初将MyTabbedPage创建为ContentPage时,功能完全正常:
- 在
MauiProgram.cs中注册单例:mauiAppBuilder.Services.AddSingleton<MyTabbedPage>(); - 主页面通过RelayCommand触发导航:
[RelayCommand] private async Task Create() => await _navigationService.NavigateToPage<MyTabbedPage>(); - 导航服务核心实现:
public async Task NavigateToPage<T>(object? parameter = null) where T : Page { var toPage = ResolvePage<T>(); if (toPage is not null) { toPage.NavigatedTo += PageNavigatedTo; var toViewModel = GetPageViewModelBase(toPage); if (toViewModel is not null) await toViewModel.OnNavigatingTo(parameter); await Navigation.PushAsync(toPage, true); toPage.NavigatedFrom += PageNavigatedFrom; } else throw new InvalidOperationException($"Unable to resolve type {typeof(T).FullName}"); }
将MyTabbedPage改为TabbedPage并添加子页面后,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" xmlns:views="clr-namespace:MyApp.Pages" x:Class="MyApp.Pages.MyTabbedPage" Title="MyTabbedPage"> <views:MyChildrenPage/> </TabbedPage>
点击导航按钮时触发错误:
Java.Lang.IllegalArgumentException: 'No view found for id 0x7f0a018b (CONFIDENTIALPATH/navigationlayout_toptabs) for fragment ViewFragment{a6b7d12} (fec1b5a7-e8fa-4129-a651-e8c4978783fb id=0x7f0a018b)'
补充信息:
- 未找到该错误与TabbedPage相关的公开解决方案
- 希望避免使用Shell
- 已遵循微软TabbedPage官方文档
- 子页面
MyChildrenPage通过以下方式绑定ViewModel:public partial class MyChildrenPage : ContentPage { public MyChildrenPage() { InitializeComponent(); var viewModel = Application.Current.MainPage.Handler.MauiContext.Services.GetService<MyChildrenViewModel>(); BindingContext = viewModel; } }
解决方案
1. 修改TabbedPage的DI注册方式
将TabbedPage从单例改为瞬时实例,单例模式会导致页面实例被复用,其内部的Android Fragment容器会因重复导航出现资源冲突:
// 替换原有的AddSingleton mauiAppBuilder.Services.AddTransient<MyTabbedPage>();
2. 修正子页面的ViewModel注入逻辑
放弃通过Application.Current手动获取服务的方式,改用构造函数注入,同时注册子页面和其ViewModel为瞬时实例:
- 在
MauiProgram.cs中添加:mauiAppBuilder.Services.AddTransient<MyChildrenPage>(); mauiAppBuilder.Services.AddTransient<MyChildrenViewModel>(); - 修改
MyChildrenPage的构造函数:public partial class MyChildrenPage : ContentPage { public MyChildrenPage(MyChildrenViewModel viewModel) { InitializeComponent(); BindingContext = viewModel; } }
MAUI会自动处理TabbedPage子页面的构造参数注入,无需额外配置。
3. 验证导航服务的页面解析逻辑
确保ResolvePage<T>()方法从DI容器中获取瞬时实例,每次导航都创建全新的TabbedPage及其子页面实例,避免复用旧实例导致的布局资源冲突。
错误根源解释
该Android端错误本质是:单例的TabbedPage实例被重复推入导航栈时,其内部封装的子页面Fragment试图附加到已被回收的布局容器中(navigationlayout_toptabs),导致系统找不到对应的视图ID。改为瞬时实例后,每次导航都会创建全新的TabbedPage和子页面,Fragment容器也会重新初始化,避免资源冲突。
内容的提问来源于stack exchange,提问作者Fernando Lopes
相关产品推荐
相关产品推荐

