こんにちは。エクセルソフトの田淵です。
日本マイクロソフトの大型有償技術イベント de:code 2016 の DEV-023 でお見せした、ちょっと頑張った Xamarin.Forms アプリの解説、その2です。
このエントリーでは主に iOS/Android ネイティブの機能を使う仕組みについてご紹介します。
ネイティブの UI や API を使う仕組み
Custom Renderer
ネイティブの UI を PCL プロジェクトから呼び出せるようにする仕組みです。
例えば角丸ボタンを作成する場合、PCL プロジェクトに次のような空の Button
を継承したクラスを用意して、
public class RoundedButton : Button { public RoundedButton() { } }
<local:RoundedButton Text="Rounded Button!"/>
と呼び出して使います。後は各プラットフォームにレンダリングする View を用意します。レンダリングする時に置き換えられます。例えば iOS では以下のように書きます。
using Phoneword; using Phoneword.iOS; [assembly: ExportRenderer(typeof(RoundedButton), typeof(RoundedButtonRenderer))] namespace Phoneword.iOS { class RoundedButtonRenderer : ButtonRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Button> e) { base.OnElementChanged(e); if (Control != null) { var c = UIColor.FromRGB(0.867f, 1.0f, 0.867f); // #ddffdd Control.Layer.CornerRadius = 25f; Control.Layer.BackgroundColor = c.CGColor; } } } }
ドキュメントは
日本語の情報は Build Insider をご覧ください。
Dependency Service
Xamarin Plugin が充実してきたため、使用頻度は減ってきていると思いますが、ネイティブの API を PCL プロジェクトからインターフェース経由で呼び出せるようにする仕組みです。
ドキュメントは こちら をご覧ください。
日本語情報は Build Insider をご覧ください。
Effect
Custom Renderer より簡単にネイティブの UI を呼び出す仕組みです。
PCL 側に次のような呼び出しクラスを用意し、
public class FocusEffect : RoutingEffect { public FocusEffect() : base("MyCompany.FocusEffect") { } }
View から Effect を指定します。
<Entry Text="{Binding FilterNumber}"> <Entry.Effects> <local:FocusEffect /> </Entry.Effects> </Entry>
後は、各ネイティブプロジェクトに実装を追加してあげます。
iOS の場合は
[assembly: ResolutionGroupName("MyCompany")] [assembly: ExportEffect(typeof(FocusEffect), "FocusEffect")] namespace PreviewerSample.iOS { public class FocusEffect : PlatformEffect { UIColor backgroundColor; protected override void OnAttached() { backgroundColor = UIColor.FromRGB(200, 170, 200); Control.BackgroundColor = backgroundColor; } protected override void OnDetached() { //throw new NotImplementedException(); } protected override void OnElementPropertyChanged(System.ComponentModel.PropertyChangedEventArgs args) { base.OnElementPropertyChanged(args); if (args.PropertyName == "IsFocused") { if (Control.BackgroundColor == backgroundColor) Control.BackgroundColor = UIColor.Clear; else Control.BackgroundColor = backgroundColor; } } } }
Android の場合は
[assembly: ResolutionGroupName("MyCompany")] [assembly: ExportEffect(typeof(FocusEffect), "FocusEffect")] namespace PreviewerSample.Droid { public class FocusEffect : PlatformEffect { Android.Graphics.Color backgroundColor; protected override void OnAttached() { backgroundColor = Android.Graphics.Color.Rgb(120, 182, 226); Control.SetBackgroundColor(backgroundColor); } protected override void OnDetached() { //throw new NotImplementedException(); } protected override void OnElementPropertyChanged(System.ComponentModel.PropertyChangedEventArgs args) { base.OnElementPropertyChanged(args); if (args.PropertyName == "IsFocused") { if (((Android.Graphics.Drawables.ColorDrawable)Control.Background).Color == backgroundColor) Control.SetBackgroundColor(Android.Graphics.Color.Transparent); else Control.SetBackgroundColor(backgroundColor); } } } }
で指定したりします。呼び出し方に何種類かありますので、お好みの方法で。
ドキュメントは
日本語の情報は @ticktackmobile さんのエントリーをご覧ください。
Xamarin Plugins
Bait and Switch という仕組みを使用してビルド時に参照ライブラリと実装ライブラリが置き換えられます。
Xamarin の中の人 @atsushieno さんが JXUG でしゃべっていただいた スライド をご覧ください。
Xamarin Plugin を作成したい方はプロジェクトテンプレートが用意されていますので、@ticktackmobile さんのエントリーをご覧ください。
続きはその3。おかしな機能をご紹介です。
http://ytabuchi.hatenablog.com/entry/dev-023-3ytabuchi.hatenablog.com
Xamarin 気になった方は
是非 ダウンロード して触ってみてください。Visual Studio 2015 をご利用の方は Update 2 にアップデートする際にカスタムインストールで Xamarin を追加しましょう。 学習用リソース や JXUG リンクページ に参考資料を纏めてますので併せてどうぞ。
Xamarin の情報が欲しい方はこのブログも購読いただいたり、私のTwitterアカウントをフォローいただいたりすると嬉しいです。
私が所属している エクセルソフト の宣伝を少しさせてください。弊社は開発者向けの様々なソフトウェアを扱っています。おなじみの ReSharper (JetBrains)、 や Atlassian の JIRA, Confluence、Office/PDF ファイルを .NET/Java で操作するライブラリ Aspose(アスポーズ)、Windows アプリ、Web ページ、iOS/Android アプリの UI テストができる TestComplete などお勧めです(^^) また、Visual Studio Professional/Enterprise with MSDN も販売してますし、日本で売っていない海外のソフトウェア、開発ツールなどを弊社経由で日本円で購入頂くことも可能です。ご興味あれば 弊社ページ を覗いてみてください。
以上です。