You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI中Shell.TitleView内容为何每隔一次页面切换就消失?

MAUI Shell TitleView Android 交替页面消失问题解决

问题现象

开发了一个带Flyout菜单的MAUI应用,导航栏汉堡按钮旁显示标题和跳转用户设置的按钮。在Android设备/模拟器上,从菜单进入的每隔一个页面,Shell.TitleView里的内容会消失——不管页面选择顺序如何,比如依次打开FirstPage、ThirdPage、SecondPage、FirstPage时,ThirdPage和第二次打开的FirstPage的TitleView都没有内容。用HorizontalStackLayout也会出现同样问题,但直接在Shell.TitleView里放Label就正常,Windows平台完全没问题。切换页面时,Grid内容会短暂正确显示约0.7秒后消失。

原因分析

这是MAUI Shell在Android平台的已知布局复用bug:当使用容器控件(Grid/HorizontalStackLayout)作为TitleView根元素时,Shell在交替加载FlyoutItem对应的页面时,没有正确维护容器的可视状态,子元素会被意外重置或隐藏。单独使用Label时不会触发这个问题,因为Shell对单一元素的状态维护逻辑不同。

解决方案

方案1:强制保持容器可视状态

修改AppShell.xaml中的Grid,添加IsVisible="True",强制控件保持可见:

<Shell.TitleView>
    <Grid x:Name="titleGrid" ColumnDefinitions="*,*" BackgroundColor="Red" IsVisible="True">
        <Label Grid.Column="0" x:Name="title" Style="{StaticResource labelPageTitle}"/>
        <Button Grid.Column="1" Text="NN" Style="{StaticResource ButtonToProfilePage}" Clicked="ProfileButton_OnClickedAsync"/>
    </Grid>
</Shell.TitleView>

方案2:导航后强制刷新布局

在AppShell.xaml.cs的OnNavigated事件中,添加强制布局刷新的代码:

protected override void OnNavigated(ShellNavigatedEventArgs args)
{
    base.OnNavigated(args);
    title.Text = Shell.Current.CurrentItem.Title;
    // 强制刷新TitleView容器布局
    titleGrid.ForceLayout();
}

方案3:升级MAUI版本

将MAUI NuGet包升级到最新稳定版,官方后续版本已经修复了多个Shell TitleView相关的Android平台bug。

替代方案

替代方案1:页面单独定义TitleView

不在Shell全局设置TitleView,而是在每个页面的XAML中单独配置:
比如FirstPage.xaml:

<ContentPage ...>
    <Shell.TitleView>
        <Grid ColumnDefinitions="*,*" BackgroundColor="Red">
            <Label Grid.Column="0" Text="First" Style="{StaticResource labelPageTitle}"/>
            <Button Grid.Column="1" Text="NN" Style="{StaticResource ButtonToProfilePage}" Clicked="ProfileButton_OnClickedAsync"/>
        </Grid>
    </Shell.TitleView>
    <!-- 页面内容 -->
</ContentPage>

这种方式每个页面的TitleView独立,不会受Shell全局复用逻辑影响。

替代方案2:自定义导航栏

隐藏Shell默认导航栏,在页面顶部使用自定义Grid作为导航栏:

  1. 在AppShell中设置全局隐藏导航栏:
<Shell ... NavBarIsVisible="False">
    <!-- FlyoutItems -->
</Shell>
  1. 在每个页面顶部添加自定义导航栏:
<ContentPage ...>
    <Grid>
        <!-- 自定义导航栏 -->
        <Grid ColumnDefinitions="*,*" BackgroundColor="Red" HeightRequest="50">
            <Label Grid.Column="0" Text="First" Style="{StaticResource labelPageTitle}" VerticalOptions="Center"/>
            <Button Grid.Column="1" Text="NN" Style="{StaticResource ButtonToProfilePage}" VerticalOptions="Center"/>
        </Grid>
        <!-- 页面内容,Margin避开导航栏 -->
        <ScrollView Margin="0,50,0,0">
            <!-- 内容 -->
        </ScrollView>
    </Grid>
</ContentPage>

原始代码参考

AppShell.xaml

<?xml version="1.0" encoding="UTF-8" ?>
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui" 
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
       xmlns:views="clr-namespace:ProfileApp.Views" 
       x:Class="ProfileApp.AppShell" 
       FlyoutBehavior="Flyout">
    <Shell.TitleView>
        <Grid ColumnDefinitions="*,*" BackgroundColor="Red">
            <Label Grid.Column="0" x:Name="title" Style="{StaticResource labelPageTitle}"/>
            <Button Grid.Column="1" Text="NN" Style="{StaticResource ButtonToProfilePage}" Clicked="ProfileButton_OnClickedAsync"/>
        </Grid>
    </Shell.TitleView>
    <FlyoutItem Title="First" >
        <ShellContent ContentTemplate="{DataTemplate views:FirstPage}" />
    </FlyoutItem>
    <FlyoutItem Title="Second">
        <ShellContent ContentTemplate="{DataTemplate views:SecondPage}" />
    </FlyoutItem>
    <FlyoutItem Title="Third">
        <ShellContent ContentTemplate="{DataTemplate views:ThirdPage}" />
    </FlyoutItem>
</Shell>

AppShell.xaml.cs

using ProfileApp.Views;

namespace ProfileApp;

public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
        Routing.RegisterRoute(nameof(ProfilePage), typeof(ProfilePage));
    }

    protected override void OnNavigated(ShellNavigatedEventArgs args)
    {
        base.OnNavigated(args);
        title.Text = Shell.Current.CurrentItem.Title;
    }

    private async void ProfileButton_OnClickedAsync(object sender, EventArgs e)
    {
        if (Shell.Current.CurrentPage is ProfilePage) return;
        await Shell.Current.GoToAsync(nameof(ProfilePage), true);
        title.Text = "Profile Settings";
    }
}

MauiProgram.cs

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
        });

    var services = builder.Services;
    services.AddTransient<AppShell>();
    services.AddTransient<FirstPage>();
    services.AddTransient<SecondPage>();
    services.AddTransient<ThirdPage>();
    services.AddTransient<ProfilePage>();
    
    return builder.Build();
}

内容的提问来源于stack exchange,提问作者Frank Mehlhop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 09:15:09