この記事は Xamarin Advent Calendar 2014 、兼 XAML Advent Calendar 2014 の9日目です。
この記事では Xamarin.Forms の時期バージョン(ver.1.3.0)で追加される機能の中から、
Styles
、Triggers
についてXAMLとC#のサンプル付きでご紹介します。また、アプリケーションのエントリ部分が変更されるので、その修正方法も併せてご紹介します。
- ver.1.3.0で追加される機能
- Xamarin.Forms.Application
- Dynamic Resource
- Styles
- Triggers
- Behaviors
- etc...
WPFなどで既に存在する機能の追加が多く、使い方も基本的に同じようです。
XAML Advent Calendar から来た方へ
Xamarin ご存知でしょうか?よく知らない方のために軽〜くご説明いたします。
Xamarin とは
- C#(.NET)で iOS、Android、Macアプリを開発できるSDK(有償)。
- そのSDKを作っている会社の名前。
Xamarin.Forms とは
- ワンソースでiOS、Android、Windows Phone の3プラットフォームの画面を作成できるフレームワーク。
- BindingやMessagingをサポートしMVVMなアプリ開発が可能。
- XAMLでViewを定義可能。(ただしコントロールは独自)
Xamarin.Froms を更新する
記事中の環境は Mac & Xamarin Studio(Stableチャンネル)です。
執筆時点の Xamarin.Forms 1.3.0 はプレビュー版です、紹介した内容は正式版で変更される可能性があります。
実行結果はiOS Simulatorのみとなっています、お許しください。
新規にソリューションを作ります。
プロジェクトのテンプレートは「Blank APP (Xamarin.Forms Portable)」を選択します。
Xamarin.Forms の更新
さて、安定版のXamarin.FormsはNuGetマネージャからダウンロード可能ですが、ver.1.3.0は現在プレビュー版であるため通常の手順では導入できません。そこで、Xamarin Forumからnupkgファイルをダウンロードし、NuGetパッケージマネージャに対してローカルディレクトリをリポジトリとして追加する必要があります。nuget.orgから取得できるようになりました。
各プロジェクトの「パッケージ」ディレクトリを右クリックして「Add Packages」を選択するとパッケージマネージャが開きます。
「Show pre-release packages」をチェックして「xamarin.forms」と検索してください。
安定板の他に「-pre」サフィックスの付いたパッケージが見つかりますので最新版に更新します。
更新に成功するパッケージのバージョンが上がります。(更新前はver.1.2.3.x)
この作業を全てのプロジェクトで行います。
Xamarin.Forms.Application に対応する
プロジェクトテンプレートをXamarin.Forms.Application
を使用するコードに修正します。
この変更により以下の機能が追加されます。
- root pageの変更を容易化
- Properties dictionaryを経由する永続的データストア
- Sleep/Resume/Start イベント
- アプリケーションレベルのresource dictionary
この対応をしないと XAMLからのView生成が失敗 します。
どうやらView要素がアプリケーションレベルのリソースディクショナリを検索できるようにするため、XAMLからのView生成処理が変更されているようです。
PCLプロジェクト
App
クラスを次のように修正します。
public class App : Application
{
public App()
{
MainPage = new ContentPage
{
Content = new Label
{
Text = "Hello, Forms !",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
},
};
}
// protected override void OnSleep()
// {
// base.OnSleep();
// }
// protected override void OnResume()
// {
// base.OnResume();
// }
// protected override void OnStart()
// {
// base.OnStart();
// }
}
App
クラスにXamarin.Forms.Application
を継承させ、最初の画面をMainPage
プロパティに格納します。
OnSleep
、OnResume
、OnStart
メソッドをoverrideするとライフサイクルイベントを捕まえられるようです。(今回は使いません)
iOSプロジェクト
AppDelegate
クラスを次のように修正します。
public partial class AppDelegate : Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Forms.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}
Androidプロジェクト
MainActivity
クラスを次のように修正します。
public class MainActivity : Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
Forms.Init(this, bundle);
LoadApplication(new App());
}
}
Windows Phoneプロジェクト
今回の手順ではWindows Phoneプロジェクトは作成されませんが一緒に解説します。
MainPage
クラスを次のように修正します。
public partial class MainPage : Xamarin.Forms.Platform.WinPhone.FormsApplicationPage
{
public MainPage()
{
InitializeComponent();
Forms.Init();
LoadApplication(new App());
}
}
XAMLコードの修正も忘れずに。
<winPhone:FormsApplicationPage
...
xmlns:winPhone="clr-namespace:Xamarin.Forms.Platform.WinPhone;assembly=Xamarin.Forms.Platform.WP8"
>
</winPhone:FormsApplicationPage>
さあ、これでXamarin.Forms 1.3.0の新機能を使う準備が整いました。
Styles を試す
PCLプロジェクトに新しいファイルを追加してください。ファイルの種類は「Forms」カテゴリにある「Forms ContentPage Xaml」です。ファイル名はStylesPage
にします。
XAML
PageのリソースディクショナリにStyle
を追加します、書き方はWPFとほぼ同じです。
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="XF13TPSample.StylesPage">
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="Label.TextColor" Value="White" />
<Setter Property="Label.BackgroundColor" Value="Gray" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="Center" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<Label
Text="Hello Styles!"
Style="{StaticResource LabelStyle}"
/>
</ContentPage.Content>
</ContentPage>
x:Key
で名前を付けてStaticResource
やDynamicResource
として参照できるようにします。Label
に適用したいのでTargetType
には"Label"
を指定します。ちなみにx:Key
のインテリセンスが効きません。
Setter
で文字色、背景色、水平位置、垂直位置を指定しています。Setter
のプロパティ指定はクラス名.プロパティ名
とした方がスムーズに解決できるそうですが、HorizontalOptions
のように省略しても反映されました。Setter
が適用されない場合は省略せずに書いてみると良いかもしれません。
Label
の方ではStyle
プロパティでリソースディクショナリのStyleをStaticResource
として参照しています。
今回はなるべく単純なサンプルにするためSetter
のみとしましたがTrigger
やBehavior
を持たせることもできます。また、他のStyle
の内容を引き継ぐBasedOn
プロパティも利用できます。
実行結果
App
クラスのコンストラクタ内をMainPage = new StylesPage ();
と書き換えて実行するとこのような結果になります。Styleに記述されたプロパティ指定(文字色、背景色、水平位置、垂直位置)がきちんと反映されています。
cs
XAMLのContentPageをC#で再現すると次のようになります。比べてみると XAMLの方が断然分かりやすいですね!
var style = new Style (typeof(Label));
style.Setters.Add (new Setter{
Property = Label.TextColorProperty,
Value = Color.White
});
style.Setters.Add (new Setter{
Property = Label.BackgroundColorProperty,
Value = Color.Gray
});
style.Setters.Add (new Setter{
Property = Label.HorizontalOptionsProperty,
Value = LayoutOptions.Center
});
style.Setters.Add (new Setter{
Property = Label.VerticalOptionsProperty,
Value = LayoutOptions.Center
});
var label = new Label{
Text = "Hello Styles!",
Style = style
};
var page = new ContentPage
{
Content = label,
};
Triggers を試す
Trigger
クラスを使ってみます。「-pre1」の時点では他にEventTrigger
、DataTrigger
、MultiTrigger
があります。
Stylesのサンプルと同じように、PCLプロジェクトに新しいファイルを追加してください。ファイル名はTriggersPage
にします。
XAML
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="XF13TPSample.TriggersPage">
<ContentPage.Content>
<Switch
HorizontalOptions="Center"
VerticalOptions="Center"
>
<Switch.Triggers>
<Trigger TargetType="Switch" Property="Switch.IsToggled" Value="true">
<Setter Property="Switch.Rotation" Value="90"/>
</Trigger>
</Switch.Triggers>
</Switch>
</ContentPage.Content>
</ContentPage>
Switch
クラス(≒トグルボタン)のTriggers
プロパティの中で直接Trigger
を定義しています。このTrigger
はSwitch
のIsToggled
プロパティがtrue
の時に発動し、角度を90度に変更します。
※2015/2/1 追記 コメントでご指摘いただきました、AndroidのテーマによってはSwitch
が表示されない場合があるようです。HeightRequest
/WidthRequest
を設定すると回避できるようです。
実行結果
App
クラスのコンストラクタ内をMainPage = new TriggersPage ();
と書き換えて実行するとこのような結果になります。スイッチがオンの時に向きが90度変わります。ぐりん
cs
こちらもXAMLをC#で再現すると次のようになります。(これ書いてて思いましたがSwitch
クラスってswitch-caseキーワードと被ってて使いづらいですね)
var s = new Switch {
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
};
var trigger = new Trigger (typeof(Switch)) {
Property = Switch.IsToggledProperty,
Value = true,
};
trigger.Setters.Add (new Setter {
Property = Switch.RotationProperty,
Value = 90.0
});
s.Triggers.Add (trigger);
var page = new ContentPage {
Content = s
};
まとめ
Styles
導入によってXAMLの利用価値がグンと上がったように思います。個人的にはXAMLでアニメーションを定義できるようになったり、ResourceDictionaryを単独で定義できるようになるともっとステキだと思います。
という訳でみんなXamrinでもXAML書きましょう!
この記事で作成したプロジェクトをGitHubに上げておきました。一から作るのが面倒な方はダウンロードして遊んでみください。
参考
On Technology with Mitch Milam » 2014 » October » 09 (Xamarin.Forms.Application 対応手順)