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

如何在MAUI中自定义底部标签页?解决安卓白层及iOS适配问题

问题描述

我创建了一个Tabbed Page,想要实现如图所示的底部标签栏样式:
目标底部标签栏样式

我在Android端使用TabbedViewHandler实现了该效果,但自定义标签栏背后出现了多余的白色图层(如图),该如何移除?同时尚未找到适用于iOS端的类似解决方案。
Android端多余白色图层问题

我在Android端尝试的代码如下:

using Microsoft.Maui.Handlers;
using Microsoft.Maui.Controls.Platform;
using System.Reflection;

#if ANDROID
using static Android.Views.ViewGroup;
using Android.Graphics.Drawables;
using Google.Android.Material.BottomNavigation;
using AndroidX.Core.View;
#endif

namespace Project.Views.Handlers
{
    public class AndroidTabbedPageHandler : TabbedViewHandler
    {
        public AndroidTabbedPageHandler()
        {
            Mapper.AppendToMapping(nameof(CustomTabbedPage), (handler, view) =>
            {
#if ANDROID
                if (view is CustomTabbedPage)
                {
                    FieldInfo tabbedPageManagerFieldInfo = typeof(TabbedPage).GetField("_tabbedPageManager", BindingFlags.NonPublic | BindingFlags.Instance);
                    object tabbedPageManager = tabbedPageManagerFieldInfo?.GetValue(view);
                    FieldInfo tabLayoutFieldInfo = tabbedPageManager?.GetType().GetField("_bottomNavigationView", BindingFlags.NonPublic | BindingFlags.Instance);
                    BottomNavigationView bottomNavigationView = tabLayoutFieldInfo?.GetValue(tabbedPageManager) as BottomNavigationView;
                    if (bottomNavigationView != null)
                    {
                        GradientDrawable drawable = new GradientDrawable();
                        drawable.SetShape(ShapeType.Rectangle);
                        drawable.SetColor(Android.Graphics.Color.White);
                        drawable.SetCornerRadius(40);
                        MarginLayoutParams layoutParams = new(LayoutParams.WrapContent, LayoutParams.WrapContent);
                        layoutParams.SetMargins(20, 0, 20, 40);
                        bottomNavigationView.LayoutParameters = layoutParams;
                        bottomNavigationView.LabelVisibilityMode = LabelVisibilityMode.LabelVisibilityUnlabeled;
                        bottomNavigationView.SetElevation(12);
                        ViewCompat.SetBackground(bottomNavigationView, drawable);
                    }
                }
#endif
            });
        }
    }
}
解决方案

Android端:移除多余白色图层

多余白色图层是TabbedPage底层父容器的默认背景,只需找到该容器并设置透明背景即可。同时建议避免反射访问私有字段(后续MAUI版本可能变更导致失效),改用更稳定的方式获取控件:

修改后的Android处理器代码:

using Microsoft.Maui.Handlers;
using Microsoft.Maui.Controls.Platform;

#if ANDROID
using static Android.Views.ViewGroup;
using Android.Graphics.Drawables;
using Google.Android.Material.BottomNavigation;
using AndroidX.Core.View;
#endif

namespace Project.Views.Handlers
{
    public class AndroidTabbedPageHandler : TabbedViewHandler
    {
        public AndroidTabbedPageHandler()
        {
            Mapper.AppendToMapping(nameof(CustomTabbedPage), (handler, view) =>
            {
#if ANDROID
                if (view is CustomTabbedPage)
                {
                    // 替代反射,直接从PlatformView获取BottomNavigationView
                    var bottomNavigationView = PlatformView.FindViewById<BottomNavigationView>(Resource.Id.bottom_navigation);
                    if (bottomNavigationView != null)
                    {
                        GradientDrawable drawable = new GradientDrawable();
                        drawable.SetShape(ShapeType.Rectangle);
                        drawable.SetColor(Android.Graphics.Color.White);
                        drawable.SetCornerRadius(40);
                        MarginLayoutParams layoutParams = new(LayoutParams.WrapContent, LayoutParams.WrapContent);
                        layoutParams.SetMargins(20, 0, 20, 40);
                        bottomNavigationView.LayoutParameters = layoutParams;
                        bottomNavigationView.LabelVisibilityMode = LabelVisibilityMode.LabelVisibilityUnlabeled;
                        bottomNavigationView.SetElevation(12);
                        ViewCompat.SetBackground(bottomNavigationView, drawable);

                        // 获取父容器并设置透明背景,移除多余白色图层
                        var parentContainer = bottomNavigationView.Parent as ViewGroup;
                        parentContainer?.SetBackgroundColor(Android.Graphics.Color.Transparent);
                    }
                }
#endif
            });
        }
    }
}

iOS端:实现圆角底部标签栏

iOS端通过自定义TabbedViewHandler修改UITabBar的样式,创建圆角背景并隐藏原生默认背景:

创建iOS平台处理器:

using Microsoft.Maui.Handlers;
using UIKit;
using CoreGraphics;

#if IOS
namespace Project.Views.Handlers
{
    public class IOSTabbedPageHandler : TabbedViewHandler
    {
        protected override void ConnectHandler(UITabBarController platformView)
        {
            base.ConnectHandler(platformView);
            
            var tabBar = platformView.TabBar;
            // 隐藏原生背景和阴影
            tabBar.ShadowImage = new UIImage();
            tabBar.BackgroundImage = new UIImage();
            
            // 创建带圆角和阴影的背景视图
            var bgView = new UIView(new CGRect(20, 0, tabBar.Bounds.Width - 40, tabBar.Bounds.Height))
            {
                BackgroundColor = UIColor.White,
                Layer = {
                    CornerRadius = 40,
                    MasksToBounds = false,
                    ShadowColor = UIColor.Black.CGColor,
                    ShadowOpacity = 0.3f,
                    ShadowOffset = new CGSize(0, 2),
                    ShadowRadius = 6
                }
            };
            // 将背景视图插入到最底层
            tabBar.InsertSubview(bgView, 0);
            
            // 调整标签项布局,适配圆角区域
            tabBar.InsetsContentViewsToSafeArea = false;
            tabBar.ItemPositioning = UITabBarItemPositioning.Fill;
            tabBar.ItemSpacing = 0;
            if (tabBar.Items != null)
            {
                tabBar.ItemWidth = (tabBar.Bounds.Width - 40) / tabBar.Items.Length;
            }
        }
    }
}
#endif

注册自定义处理器

在MauiProgram.cs中注册两个平台的处理器:

builder.ConfigureMauiHandlers(handlers =>
{
#if ANDROID
    handlers.AddHandler<CustomTabbedPage, AndroidTabbedPageHandler>();
#endif
#if IOS
    handlers.AddHandler<CustomTabbedPage, IOSTabbedPageHandler>();
#endif
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 09:40:32