しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

Xamarin.Forms でプラットフォームごとに XAML の ResourceDictionary を割り当てる

TechCrunch の RSS リーダーですが、iOS で起動すると・・・

f:id:matatabi_ux:20150823132747p:plain

配色やばい・・・ということでちゃんと Andorid & Windows Phone の暗色テーマと iOS 用の明色テーマを明示的に指定するようにしたいと思います

以前プラットフォームごとにリソースを定義する方法を下記の記事にしましたが、今回は用途を絞り込めるのでもっとかんたんにやってみたいと思います


まずは Xamarin.Forms 共有プロジェクト側に Themes フォルダを追加し、LightThemeResources と DarkThemeResources という名前で Forms Xaml Page を追加します

f:id:matatabi_ux:20150823133527p:plain

XAML 側は ContentPage を ContentView に変更してこんな感じに記述

<?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="XamarinReader.Themes.LightThemeResources">
  <ContentView.Resources>
    <ResourceDictionary>
      <x:String x:Key="BackgroundColor">#ecf0f1</x:String>
      <x:String x:Key="ForegroundColor">#33333c</x:String>
      <x:String x:Key="HeaderBackgroundColor">#2c3e50</x:String>
      <x:String x:Key="HeaderForegroundColor">#bdc3c7</x:String>
      <x:String x:Key="HeaderLogoColor">#1abc9c</x:String>
      <x:String x:Key="ListItemBackgroundColor">#bdc3c7</x:String>
      <x:String x:Key="ListItemTitleColor">#2980b9</x:String>
    </ResourceDictionary>
  </ContentView.Resources>
</ContentView>

コードビハインドも同様に ContentPage を ContentView に変更

/// <summary>
/// Light theme resources
/// </summary>
public partial class LightThemeResources : ContentView
{
    /// <summary>
    /// Constructor
    /// </summary>
    public LightThemeResources()
    {
        this.InitializeComponent();
    }
}

ちなみに暗色テーマはこんな配色を指定

<?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="XamarinReader.Themes.DarkThemeResources">
  <ContentView.Resources>
    <ResourceDictionary>
      <x:String x:Key="BackgroundColor">Black</x:String>
      <x:String x:Key="ForegroundColor">#bdc3c7</x:String>
      <x:String x:Key="HeaderBackgroundColor">#20202a</x:String>
      <x:String x:Key="HeaderForegroundColor">#bdc3c7</x:String>
      <x:String x:Key="HeaderLogoColor">#1abc9c</x:String>
      <x:String x:Key="ListItemBackgroundColor">#1c1c1c</x:String>
      <x:String x:Key="ListItemTitleColor">#2980b9</x:String>
    </ResourceDictionary>
  </ContentView.Resources>
</ContentView>

あとは App.cs を修正するだけ

/// <summary>
/// Application class
/// </summary>
public class App : Application
{
    /// <summary>
    /// Dependency injection container
    /// </summary>
    public IUnityContainer Container = new UnityContainer();

    /// <summary>
    /// Costructor
    /// </summary>
    public App()
    {
        this.Container.RegisterType<INewsFeedService, NewsFeedService>(new ContainerControlledLifetimeManager());
        this.Container.RegisterType<ITranslateService, TranslateService>(new ContainerControlledLifetimeManager());

        switch (Device.OS)
        {
            case TargetPlatform.iOS:
                App.Current.Resources = new LightThemeResources().Resources;
                break;

            default:
                App.Current.Resources = new DarkThemeResources().Resources;
                break;
        }

        this.MainPage = new TopPage();
    }
}

これで起動した結果は下記の通り

配色を明示的に指定できました