如何在Xamarin Forms中更改TabBar和NavigationBar的颜色?

18

我有一个 Xamarin Forms 应用程序,目前正在为iOS编写代码。在我的设置中,我有一个选项可以更改应用程序的主题(暗色和亮色)。这基本上只是更改页面的背景颜色和文本颜色。现在我想做的是能够更改 TabBarSelectedImageTintColorBarTintColor 以及 NavigationBarBarTintColorTintColor。目前我已经为分页标签创建了一个渲染器:

protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
   base.OnElementChanged(e);
   App.theme = (Theme)App.DB.GetIntSetting("ThemeColor");
   switch (App.theme)
   {
      case Theme.Dark:
      {
         TabBar.SelectedImageTintColor = UIColor.FromRGB(255, 165, 0);
         TabBar.BarTintColor = UIColor.Black;
         break;
      }
      case Theme.Light:
      {
         TabBar.SelectedImageTintColor = UIColor.FromRGB(60, 132, 60);
         TabBar.BarTintColor = UIColor.White;
         break;
      }
   }
}

目前这些颜色只在您首次启动应用程序时生效。

输入图像描述

我研究了这个问题,但是没有找到任何人如何解决这个问题的答案。

我知道Xamarin已经发生了许多变化,因此我想了解是否有任何最新的发展或新的方法来解决这个问题。作为应用程序要求的一部分,我愿意考虑任何可能的建议以更改这些颜色。

编辑:

我的Tabbed页面是按以下方式创建的:

public partial class MainPage : TabbedPage
{
   public MainPage()
   {
      InitializeComponent();
      var phrasesPage = new NavigationPage(new PhrasesPage())
      {
         Title = "Play",
         Icon = "play1.png"
      };
      var settingsPage = new NavigationPage(new SettingsPage())
      {
         Title = "Settings",
         Icon = "settings.png"
      };
      // other declarations here

      Children.Add(phrasesPage);
      Children.Add(settingsPage);
      // and more
   }
}

比如,如果我选择暗色主题,那么TabBarNavigationBar的背景颜色将会是黑色,TabBar所选中的图像会是橙色,而NavigationBar的文本将会是白色。同样地,如果我选择亮色主题,那么TabBarNavigationBar的背景颜色将会是白色,TabBar所选中的图像会是绿色,而NavigationBar的文本将会是黑色。


你是在使用XAML还是直接编写代码来创建视图? - Dan Siegel
你想要什么?是想要改变选项卡栏的图标颜色还是背景颜色? - KKRocks
@KKRocks请检查我的编辑。谢谢。 - user6742877
好的,你在这里遇到了什么问题? - KKRocks
@KKRocks --> 目前这些颜色只会在您第一次启动应用程序时生效。我希望它可以在我更改主题时随之改变。 - user6742877
3个回答

9

我认为问题在于你没有监听并处理主题变化。你是在 OnElementChanged 中设置颜色,但当你改变主题时,它不会再被调用。

你可以创建一个属性,该属性将触发一个事件,你可以在自定义渲染器中订阅该事件。例如,如果你在你的 App 类中创建该属性,则在自定义的 TabbedPage 渲染器中可以进行如下操作:

protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
    base.OnElementChanged(e);

    if(e.OldElement != null)
    {
        App.Current.PropertyChanged -= Current_PropertyChanged;
        return;
    }

    App.Current.PropertyChanged += Current_PropertyChanged; //subscribe to the App class' built in property changed event
    UpdateTheme();
}

void Current_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    if(e.PropertyName == "DarkTheme")
    {
        UpdateTheme();
    }
}

由于导航栏是由NavigationPage控制的,因此您还需要在那里监听属性更改。幸运的是,您不需要使用自定义渲染器,因为您可以使用Forms属性更改栏和文本颜色。因此,您可以创建一个继承自NavigationPage的类并订阅事件:

public class CustomNavigationPage : NavigationPage
{
    public CustomNavigationPage(Page root) : base(root)
    {
        if(Device.OS == TargetPlatform.iOS)
        {
            App.Current.PropertyChanged += Current_PropertyChanged;
        }
    }
}

我创建了一个示例项目,以演示所有相关技术,你可以查看一下 :)

谢谢。我尝试了你的示例项目,正是我想要的。我会把你的代码融入到我的项目中。在它能够正常工作时,我会通知你的。 - user6742877

1
你可以使用选项卡的属性来在需要时更改背景和图标颜色。
 TabBar.TintColor = UIColor.White; // changer as per your need for tab icon's color
TabBar.BarTintColor = UIColor.Black; // changer as per your need for tabbar's backgroungcolor 

与导航相同。
this.NavigationController.NavigationBar.TintColor = UIColor.White;//change as per your need for tab icon color

this.NavigationController.NavigationBar.BarTintColor = UIColor.Black;// changer as per your need for Navbar' backgroungcolor 

如上面我问题中已经提到的。我使用了 TabBar.TintColor = UIColor.White; 等等。我的问题是当我从深色主题切换到白色主题或者相反时,更改不会立即生效,除非退出应用程序并重新启动。 - user6742877
你使用了相同的 TabBar 引用吗? - KKRocks
你需要使用在应用程序启动时初始化的相同的tabbarcontroller引用。 - KKRocks
你在AppDelegate中配置TabBar了吗? - KKRocks

0
你知道 Xamarin Forms 中的“动态资源”特性吗?
我将提供我的实现方式。可能不是很容易,但我认为它可以工作。
步骤1:在app.xaml中设置以下键和默认图标。
<FileImageSource x:Key="PlayIconKey">playdark.png</FileImageSource>
<FileImageSource x:Key="AboutIconKey">aboutdark.png</FileImageSource>

and

<Image Source="{ DynamicResource PlayIconKey }" />
<Image Source="{ DynamicResource AboutIconKey}" />

步骤2:在您的选项卡页面集中设置如下

var phrasesPage = new NavigationPage(new PhrasesPage())
{
 Title = "Play",
 Icon = Application.Current.Resources["PlayIconKey"]
};

对于TabbedPage中的其他页面也是如此

步骤3:现在当您更改设置时,只需设置即可

Application.Current.Resources["PlayIconKey"] = "playlight.png" 

以此方法,您可以在一个地方更改所有图标。

请告诉我您对此的意见。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接