maui中安卓端切换标签页

maui中安卓端切换标签页WebView

maui中安卓端切换标签页取消滑动切换,只能点击

在电脑端是点击切换,但是在安卓端 左右滑动也可以切换,能不能取消滑动切换,只能点击

 <!-- 第一个标签页:音乐播放器 -->
 <ContentPage Title="🎵音乐播放" IconImageSource="🎵">
    <!-- 第二个标签页:网页浏览 -->
    <ContentPage Title="🌐网页浏览" IconImageSource="🌐">
        <Grid>
            <WebView x:Name="WebBrowser" Source="https://www.2t58.com/list/djwuqu.html" VerticalOptions="Fill" HorizontalOptions="Fill" />
        </Grid>
    </ContentPage> 在电脑端是点击切换,但是在安卓端 左右滑动也可以切换,能不能取消滑动切换,只能点击

你这个效果是 .NET MAUI 的 TabbedPage 默认行为:

  • Android 上,Tab 切换除了点击 TabBar,还支持 左右滑动手势切换
  • Windows / 桌面端,默认只支持点击。

如果你只想保留 点击切换,需要禁用 ViewPager 的滑动手势。MAUI 里目前没有直接的 XAML 属性能关掉,只能通过 平台定制(Handler / CustomRenderer) 来实现。


✅ 解决方案(禁止 Android 左右滑动切换)

创建一个 自定义 Handler 来禁用 ViewPager2 的滑动:

1. 新建一个类(例如 NoSwipeTabbedPage

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MauiApp1.Controls
{
    public class NoSwipeTabbedPage : TabbedPage
    {
    }
}

2. 在 Platforms/Android 下加 Handler 映射

using Android.Views;
using AndroidX.RecyclerView.Widget;
using AndroidX.ViewPager2.Widget;
using Microsoft.Maui.Handlers; 
using View = Android.Views.View;

namespace MauiApp1.Platforms.Android
{
    public class NoSwipeTabbedPageHandler : TabbedViewHandler
    {
        public NoSwipeTabbedPageHandler() : base(Mapper)
        {
        }

        public static new PropertyMapper<TabbedPage, TabbedViewHandler> Mapper =
            new PropertyMapper<TabbedPage, TabbedViewHandler>(TabbedViewHandler.Mapper)
            {
                [nameof(TabbedPage.CurrentPage)] = MapCurrentPage
            };

        private static void MapCurrentPage(TabbedViewHandler handler, TabbedPage page)
        {
            //// 调用默认实现
            //if (TabbedViewHandler.Mapper.TryGetValue(nameof(TabbedPage.CurrentPage), out var map))
            //{
            //    map.Invoke(handler, page);
            //}

            // 然后禁止滑动
            if (handler.PlatformView is ViewPager2 viewPager)
            {
                if (viewPager.GetChildAt(0) is RecyclerView recyclerView)
                {
                    recyclerView.SetOnTouchListener(new BlockSwipeTouchListener());
                }
            }
        }

        private class BlockSwipeTouchListener : Java.Lang.Object, View.IOnTouchListener
        {
            public bool OnTouch(View? v, MotionEvent? e)
            {
                return true; // 始终消费事件,禁止滑动
            }
        }
    }
}

3. 在 MauiProgram.cs 里注册 Handler

using YourApp.Controls;
using YourApp.Platforms.Android;

builder.ConfigureMauiHandlers(handlers =>
{
#if ANDROID
    handlers.AddHandler(typeof(NoSwipeTabbedPage), typeof(NoSwipeTabbedPageHandler));
#endif
});

4. 使用方式

把你的页面 TabbedPage 换成 NoSwipeTabbedPage

<?xml version="1.0" encoding="utf-8" ?>
<controls:NoSwipeTabbedPage
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:controls="clr-namespace:MauiApp1.Controls"
    x:Class="YourApp.MainPage">

    <!-- 第一个标签页 -->
    <ContentPage Title="🎵音乐播放" IconImageSource="🎵">
        ...
    </ContentPage>

    <!-- 第二个标签页 -->
    <ContentPage Title="🌐网页浏览" IconImageSource="🌐">
        <Grid>
            <WebView x:Name="WebBrowser"
                     Source="https://www.2t58.com/list/djwuqu.html"
                     VerticalOptions="Fill"
                     HorizontalOptions="Fill"/>
        </Grid>
    </ContentPage>

</controls:NoSwipeTabbedPage>

这样在 Android 上就不能左右滑动切换,只能点击 Tab 切换; 在 Windows / iOS 上不受影响。

要不要我帮你再给出一个 iOS 禁用滑动的写法(虽然 iOS 默认没左右滑动切换)

没有<controls:选项 🔑 关键点

  • xmlns:controls="clr-namespace:MauiApp1.Controls" 必须对应你 C# 文件里定义的命名空间

  • 如果你的项目不叫 MauiApp1,或者 NoSwipeTabbedPage.cs 在别的命名空间下,就要改成实际的命名空间。

  • 如果 NoSwipeTabbedPage单独的类库 里,还需要加 ;assembly=库名,例如:

    xmlns:controls="clr-namespace:MyLib.Controls;assembly=MyLib"
    

改成了 <controls:NoSwipeTabbedPage> 之后,XAML 报错提示这些属性(BackgroundColorBarBackgroundColorSelectedTabColorUnselectedTabColor)在 MainPage 上不存在。

你在 XAML 顶部写了

x:Class="MauiApp1.MainPage"

这会让编译器认为 MainPage.xaml 对应的 C# 后置类是 MauiApp1.MainPage : NoSwipeTabbedPage,但是它仍然用 MainPage 来做类型检查,导致找不到 TabbedPage 的属性。

✅ 两种解决方案

方案一:把 MainPage 继承自 NoSwipeTabbedPage

打开 MainPage.xaml.cs,把它的基类从 ContentPage 改为 NoSwipeTabbedPage

public partial class MainPage : NoSwipeTabbedPage

这样,MainPage 本身就是一个 NoSwipeTabbedPage,XAML 里的属性(BackgroundColorBarBackgroundColor 等)就能识别了。

方案二:不修改 MainPage,直接把 NoSwipeTabbedPage 用作 Shell 的页面

如果你想保留 MainPage : ContentPage,也可以新建一个 TabbedHostPage.xaml

<controls:NoSwipeTabbedPage
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:controls="clr-namespace:MauiApp1.Controls"
    x:Class="MauiApp1.TabbedHostPage"
    BackgroundColor="#F5F5F5"
    BarBackgroundColor="#FFFFFF"
    SelectedTabColor="#1DB954"
    UnselectedTabColor="#666666">

    <ContentPage Title="🎵音乐播放">
        <!-- 播放器内容 -->
    </ContentPage>

    <ContentPage Title="🌐网页浏览">
        <WebView Source="https://www.2t58.com/list/djwuqu.html" />
    </ContentPage>

</controls:NoSwipeTabbedPage>

然后在 TabbedHostPage.xaml.cs 里继承 NoSwipeTabbedPage

using MauiApp1.Controls;

namespace MauiApp1;

public partial class TabbedHostPage : NoSwipeTabbedPage
{
    public TabbedHostPage()
    {
        InitializeComponent();
    }
}
这样就不会和 MainPage 冲突了。

🔑 总结

  • 如果你要把 MainPage 就当作 NoSwipeTabbedPage修改 MainPage.xaml.cs 继承自 NoSwipeTabbedPage(推荐做法)。
  • 如果 MainPage 本来只是个普通 ContentPage → 新建一个 TabbedPage 容器页面,不要混用。

在电脑端可以WebView 里面打开子页面,为什么安卓端不可以

<!-- 第一个标签页:音乐播放器 -->
 <ContentPage Title="🎵音乐播放" IconImageSource="🎵">
    <!-- 第二个标签页:网页浏览 -->
    <ContentPage Title="🌐网页浏览" IconImageSource="🌐">
        <Grid>
            <WebView x:Name="WebBrowser" Source="https://www.2t58.com/list/djwuqu.html" VerticalOptions="Fill" HorizontalOptions="Fill" />
        </Grid>
    </ContentPage> 在电脑端可以WebView 里面打开子页面,为什么安卓端不可以

用多个页面 试试呢

或者一个页面 全操作结束

通过 NuGet 安装其他插件显示

 <controls:NoSwipeTabbedPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
            x:Class="MauiApp1.MainPage"
            xmlns:controls="clr-namespace:MauiApp1.Controls" 
            BackgroundColor="#F5F5F5"  >   <!-- 第一个标签页:音乐播放器 -->
    <!--<ContentPage Title="🎵音乐播放" IconImageSource="🎵">--> <!--</ContentPage>-->
 
 <!-- 第二个标签页:网页浏览 --><!-- 即使没有这个标签 安卓端一直往下滑动后 界面会卡住
 <ContentPage Title="🌐网页浏览" IconImageSource="🌐">
     <Grid>
        // <WebView x:Name="WebBrowser" Source="https://www.2t58.com/list/djwuqu.html" VerticalOptions="Fill" HorizontalOptions="Fill"  Navigating="OnWebViewNavigating" />
     </Grid>
<!--</controls:NoSwipeTabbedPage>-->
 </ContentPage>  检查一下,为什么在安卓端一直往下滑动后 界面会卡住 
直接原因就是用了标签页 不能安卓界面使用标签页,界面会卡住 取消改成ContentPage后就不卡了

启动入口:MainPage = new AppShell();

页面组织:用 AppShell.xaml 来放 Tab

页面跳转:用 Shell.Current.GoToAsync(...)