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

Xamarin Forms 如何设置More按钮内标签页的背景色

Xamarin.Forms Shell More页面样式不生效问题

问题场景

基于Xamarin.Forms.Shell开发应用实现布局与导航功能时,TabBar中添加的标签数量超过5个后,Android、iOS平台会原生生成More按钮收纳超出的标签。在XAML中配置Shell.BackgroundColor、Shell.TabBarBackgroundColor等自定义颜色属性后,More按钮展开的收纳页面没有应用自定义样式。

对应App Shell的XAML代码如下:

<Shell.Resources>
    <ResourceDictionary>
        <Style x:Key="BaseStyle"  TargetType="Element">
            <Setter Property="Shell.BackgroundColor" 
                    Value="{x:Static core:Colors.Background}" />
            <Setter Property="Shell.ForegroundColor" 
                    Value="White" />
            <Setter Property="Shell.TabBarBackgroundColor"
                    Value="{x:Static core:Colors.Background}" />
            <Setter Property="Shell.TabBarTitleColor"
                    Value="{x:Static core:Colors.Selection}" />
            <Setter Property="Shell.TabBarUnselectedColor"
                    Value="White" />
        </Style>
    </ResourceDictionary>
</Shell.Resources>

<ShellItem Route="Home">
    <ShellContent ContentTemplate="{DataTemplate core:HomePage}"/>
</ShellItem>

<TabBar Route="Tabs" Style="{x:StaticResource BaseStyle}">
    <Tab Route="TabSearch"
         Icon="ic_list_white"
         Title="Search">
        <ShellContent ContentTemplate="{DataTemplate core:SearchPage}"/>
    </Tab>
    <Tab
        Icon="ic_filter_list_white"
        Title="Filter">
        <ShellContent ContentTemplate="{DataTemplate core:FilterPage}"/>
    </Tab>
    
    <Tab Icon="ic_star_white"
        Title="Favourites">
        <ShellContent ContentTemplate="{DataTemplate core:FavouritesPage}"/>
    </Tab>
    
    <Tab Icon="ic_remove_red_eye_white"
        Title="Seen">
        <ShellContent ContentTemplate="{DataTemplate core:SeenPage}"/>
    </Tab>

    <Tab Icon="ic_shopping_cart_white" Title="{x:Static resources:Strings.MAINPAGE_MENU_PURCHASE_PACKAGES}">
        <ShellContent ContentTemplate="{DataTemplate core:PackagePurchasePage}"/>
    </Tab>

    <Tab Icon="ic_sync_white" Title="{x:Static resources:Strings.MAINPAGE_MENU_RESTORE_PURCHASES}"  >
        <ShellContent ContentTemplate="{DataTemplate core:RestorePurchasePage}"/>
    </Tab>

    <Tab Icon="ic_settings_white" Title="{x:Static resources:Strings.MAINPAGE_MENU_SETTINGS}"  >
        <ShellContent ContentTemplate="{DataTemplate core:SettingsPage}"/>
    </Tab>

    <Tab Icon="ic_help_white" Title="{x:Static resources:Strings.MAINPAGE_MENU_ABOUT}" >
        <ShellContent ContentTemplate="{DataTemplate views:AboutShell }"/>
    </Tab>
</TabBar>

效果对比:

  • 已应用自定义样式的TabBar:已应用样式的TabBar
  • More按钮展开的收纳页未应用自定义样式:More按钮展开页效果

目标:让More按钮展开页面的样式与TabBar已配置的自定义样式完全统一。


解决方案

Shell的More页面由各平台原生控件渲染,不会自动继承Shell层定义的TabBar颜色属性,需要通过平台自定义渲染器单独配置样式。

Android平台实现

在Android项目中添加自定义Shell渲染器,重写More页面相关的样式回调:

using Android.Content;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
// 替换为你自己的Android项目命名空间
using YourAppName.Droid;

[assembly: ExportRenderer(typeof(AppShell), typeof(CustomShellRenderer))]
namespace YourAppName.Droid
{
    public class CustomShellRenderer : ShellRenderer
    {
        public CustomShellRenderer(Context context) : base(context) { }

        protected override IShellMoreViewAppearanceTracker CreateMoreViewAppearanceTracker(ShellItem shellItem)
        {
            return new CustomMoreViewAppearance();
        }
    }

    public class CustomMoreViewAppearance : IShellMoreViewAppearanceTracker
    {
        public void ResetAppearance(MoreView view, ShellMoreViewAppearance appearance)
        {
            // 设置More页面整体背景色,复用你定义的全局背景色
            view.SetBackgroundColor(YourAppName.Colors.Background.ToAndroid());
            
            // 修改列表项文字的选中/未选中颜色
            var listView = view.FindViewById<ListView>(Android.Resource.Id.List);
            listView.Adapter = new ColorConfiguredListAdapter(
                listView.Adapter,
                Color.White.ToAndroid(),
                YourAppName.Colors.Selection.ToAndroid()
            );

            // 修改顶部导航栏背景色
            if (view.Parent is ViewGroup parent)
            {
                for (int i = 0; i < parent.ChildCount; i++)
                {
                    var child = parent.GetChildAt(i);
                    if (child is FrameLayout navBar)
                    {
                        navBar.SetBackgroundColor(YourAppName.Colors.Background.ToAndroid());
                        break;
                    }
                }
            }
        }

        public void SetAppearance(MoreView view, ShellMoreViewAppearance appearance)
        {
            ResetAppearance(view, appearance);
        }
    }

    internal class ColorConfiguredListAdapter : BaseAdapter
    {
        private readonly IListAdapter _innerAdapter;
        private readonly Android.Graphics.Color _normalTextColor;
        private readonly Android.Graphics.Color _selectedTextColor;

        public ColorConfiguredListAdapter(IListAdapter innerAdapter, Android.Graphics.Color normalTextColor, Android.Graphics.Color selectedTextColor)
        {
            _innerAdapter = innerAdapter;
            _normalTextColor = normalTextColor;
            _selectedTextColor = selectedTextColor;
        }

        public override int Count => _innerAdapter.Count;
        public override Java.Lang.Object GetItem(int position) => _innerAdapter.GetItem(position);
        public override long GetItemId(int position) => _innerAdapter.GetItemId(position);

        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            var itemView = _innerAdapter.GetView(position, convertView, parent);
            if (itemView is CheckedTextView textView)
            {
                textView.SetTextColor(new ColorStateList(
                    new[] { new[] { -Android.Resource.Attribute.StateChecked }, new[] { Android.Resource.Attribute.StateChecked } },
                    new[] { _normalTextColor, _selectedTextColor }
                ));
            }
            return itemView;
        }
    }
}

iOS平台实现

在iOS项目中添加自定义Shell渲染器,修改More页面对应的导航控制器和列表样式:

using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
// 替换为你自己的iOS项目命名空间
using YourAppName.iOS;

[assembly: ExportRenderer(typeof(AppShell), typeof(CustomShellRenderer))]
namespace YourAppName.iOS
{
    public class CustomShellRenderer : ShellRenderer
    {
        public override void ViewDidLayoutSubviews()
        {
            base.ViewDidLayoutSubviews();
            // 匹配到More页面的导航控制器
            if (SelectedViewController is UINavigationController nav && nav.TopViewController is UITableViewController morePage)
            {
                // 配置列表背景色
                morePage.TableView.BackgroundColor = YourAppName.Colors.Background.ToUIColor();
                // 配置导航栏样式
                nav.NavigationBar.BarTintColor = YourAppName.Colors.Background.ToUIColor();
                nav.NavigationBar.TintColor = UIColor.White;
                nav.NavigationBar.TitleTextAttributes = new UIStringAttributes
                {
                    ForegroundColor = UIColor.White
                };
            }
        }

        protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
        {
            return new CustomTabBarAppearance();
        }
    }

    public class CustomTabBarAppearance : ShellTabBarAppearanceTracker
    {
        public override void UpdateLayout(UITabBarController controller)
        {
            base.UpdateLayout(controller);
            // 初始化时配置More页面导航栏样式
            var moreNav = controller.MoreNavigationController;
            moreNav.NavigationBar.BarTintColor = YourAppName.Colors.Background.ToUIColor();
            moreNav.NavigationBar.TintColor = UIColor.White;
            moreNav.NavigationBar.TitleTextAttributes = new UIStringAttributes
            {
                ForegroundColor = UIColor.White
            };
        }
    }
}

配置说明

  • 将代码中YourAppName替换为你项目的实际根命名空间,颜色直接复用XAML中定义的全局静态颜色资源即可,保证全局样式统一。
  • 如果需要适配深色模式,在平台主题切换回调中重新执行样式设置逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:09:17