年末の Xamarin × ResourceDictionary でプラットフォームごとに配色を変えたい の続きです
前回は App.xaml に ResourceDictionary を追加し、
そこで、プラットフォームごとのリソース定義を別々の XAML ファイルに分割することを試みてみます
ソリューション全体はこんな感じになります
まずは App.xaml を修正
<?xml version="1.0" encoding="utf-8" ?> <AppBase xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="XamarinUnityInjection.App"> <AppBase.Resources> <ResourceDictionary/> </AppBase.Resources> </AppBase>
ResourceDictionary を空にしただけ!
次に ThemeResources-iOS.xaml を Xamarin.Forms の Forms Xaml Page として Themes フォルダを作ってそこに追加します
namespace XamarinUnityInjection.iOS { /// <summary> /// iOS 用テーマリソース定義 View /// </summary> public partial class ThemeResources : ContentView { /// <summary> /// コンストラクタ /// </summary> public ThemeResources() { this.InitializeComponent(); } } }
ContentView を継承するように変更して、名前空間を iOS 付きに変更し・・・
<?xml version="1.0" encoding="utf-8" ?> <ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="XamarinUnityInjection.iOS.ThemeResources"> <ContentView.Resources> <ResourceDictionary> <x:String x:Key="HourHandColor">#FFFF8469</x:String> <x:String x:Key="MinuteHandColor">#FFFF461C</x:String> <x:String x:Key="SecondHandColor">#FFCC3816</x:String> <x:String x:Key="TickColor">#FF7F4234</x:String> <x:String x:Key="NumberColor">#FF7F230E</x:String> </ResourceDictionary> </ContentView.Resources> </ContentView>
XAML の方はこんな感じでカラーコードを String 型で ResourceDictionary 内に記述します
同様に Windows Phone の方も ThemeResources-WinPhone.xaml を追加します
namespace XamarinUnityInjection.WinPhone { /// <summary> /// Windows Phone 用テーマリソース定義 View /// </summary> public partial class ThemeResources : ContentView { /// <summary> /// コンストラクタ /// </summary> public ThemeResources() { this.InitializeComponent(); } } }
名前空間が WinPhone 付きになっているだけ
<?xml version="1.0" encoding="utf-8" ?> <ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="XamarinUnityInjection.WinPhone.ThemeResources"> <ContentView.Resources> <ResourceDictionary> <x:String x:Key="HourHandColor">#FF08007F</x:String> <x:String x:Key="MinuteHandColor">#FF0D00CC</x:String> <x:String x:Key="SecondHandColor">#FF1000FF</x:String> <x:String x:Key="TickColor">#FF2C267F</x:String> <x:String x:Key="NumberColor">#FF584CFF</x:String> </ResourceDictionary> </ContentView.Resources> </ContentView>
XAML の方は Windows Phone 用にカラーコードの値を変えます
最後に App.xaml.cs の改修
/// <summary> /// 共通 アプリケーションクラス /// </summary> public partial class App : AppBase { /// <summary> /// アプリケーションクラス参照 /// </summary> public static readonly App Current; ~ 中略 ~ /// <summary> /// メイン画面を取得します /// </summary> /// <returns>メイン画面</returns> public static Page GetMainPage() { // テーマリソースの読み込み ContentView theme = new ContentView(); switch (Device.OS) { case TargetPlatform.iOS: theme = new XamarinUnityInjection.iOS.ThemeResources(); break; case TargetPlatform.WinPhone: theme = new XamarinUnityInjection.WinPhone.ThemeResources(); break; } // AppResources にテーマリソースを上書き・追加します foreach (var resource in theme.Resources) { if (App.Current.Resources.ContainsKey(resource.Key)) { App.Current.Resources[resource.Key] = resource.Value; } else { App.Current.Resources.Add(resource.Key, resource.Value); } } return new TopPage(); } }
GetMainPage の内部でプラットフォームごとに ThemeResources の ContentView をインスタンス化して、AppResource の ResourceDictionary に追加するようにしました
リソースキーが重複するものは上書きするようにしています
さていつものように動作確認!
テーマリソースをプラットフォームごとに別ファイル定義にしてもちゃんとできましたね!