web-dev-qa-db-ja.com

Xamarinフォームのタブバーとナビゲーションバーの色を変更する方法

Xamarin Formsアプリケーションと私は現在iOSのコードに取り組んでいます。私の設定では、アプリケーションのテーマ(ダークとライト)を変更するオプションがあります。これは基本的に、ページの背景色とテキスト色を変更するだけです。次に、SelectedImageTintColorBarTintColorTabBar、およびBarTintColorTintColor/NavigationBar。現時点では、タブ付きページのレンダラーを作成しています。

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;
      }
   }
}

現在、これらの色は、アプリケーションを最初に起動したときにのみ有効になります。

enter image description here

私はこの問題を調査しましたが、この問題の解決方法について誰からも答えを見つけることができませんでした。

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のテキストは白くなります。同様に、ライトテーマを選択すると、TabBarおよびNavigationBarの背景色は白になり、TabBarの選択された画像は緑になり、NavigationBarのテキストは黒になります。

17
user6742877

問題は、テーマの変更を聞いて処理していないことだと思います。 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;
        }
    }
}

私は サンプルプロジェクト を作成しましたが、これをすべて確認できるので、チェックアウトできます:)

8
jimmgarr

タブバーのプロパティを使用して、必要なときにいつでも背景とアイコンの色を変更できます。

 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 
1
KKRocks

Xamarinフォームの「動的リソース」機能について知っていますか?

簡単な方法ではないかもしれませんが、うまくいくと思います。

ステップ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" 

その他のアイコンはこちら。

このアプローチを使用すると、すべてのアイコンを1か所で変更できます。これについてのあなたの意見を教えてください。

0