ぴーさんログ

だいたいXamarin.Formsのブログ

【Xamarin.Forms 2.2】Embedded Platform-Specific Controls in Xamarin.Forms

Xamarin.Forms 2.2から Layout.ChildrenContentView.Content に各プラットフォームのネイティブコントロールを埋め込めるようになり、Evolve 2016のキーノートでも紹介されました。 このフィーチャーを使うとCustomRendererよりもカジュアルにネイティブコントロールを利用できます。

キーノートのブログ

Live from Evolve: Faster and Easier Mobile App Development with Xamarin.Forms | Xamarin Blog

ドキュメント

Native Embedding - Xamarin

条件

ネイティブコントロールの埋め込みを行うにはSharedプロジェクト内のコードで、プラットフォーム毎に#ifディレクティブで記述します。PCLプロジェクトでは使用できません。

サンプルコード

次のようなコードをSharedプロジェクトに追加すると、ネイティブコントロールを埋め込む事ができます。

using System;
using Xamarin.Forms;

#if __IOS__
using Xamarin.Forms.Platform.iOS;
using UIKit;
#elif __ANDROID__
using Xamarin.Forms.Platform.Android;
using Android.Widget;
#endif

namespace XFApp25
{
    public class MyPage : ContentPage
    {
        public MyPage ()
        {
            var text = "Embedded Platform-Specific Control in Xamarin.Forms";

            var stackLayout = new StackLayout {
                VerticalOptions = LayoutOptions.Center,
                HorizontalOptions = LayoutOptions.Center,
            };
#if __IOS__
            var uiLabel = new UILabel {
                MinimumFontSize = 14f,
                Lines = 0,
                LineBreakMode = UILineBreakMode.WordWrap,
                Text = text + "(iOS)",
            };
            // StackLayoutにUILabelが追加できる!
            stackLayout.Children.Add (uiLabel);
            // これもOK
            //Content = uiLabel.ToView ();
#elif __ANDROID__
            var textView = new TextView(Forms.Context) {
                Text = text + "(Android)",
                TextSize = 14,
            };
            stackLayout.Children.Add (textView);
            // これもOK
            //Content = textView.ToView ();
#endif
            Content = stackLayout;
        }
    }
}

仕組み

LayoutExtensionsクラスに定義された2つの拡張メソッドが使用します。

  • ToView - ネイティブコントロールをラップしてXamarin.FormsのViewに変換する拡張メソッド
  • Add - IList<View>、つまりLayout.Childrenに対する拡張メソッド(内部でToViewを呼ぶ)

これらの拡張メソッドを使うためには各名前空間の参照が必要です。

  • iOS – Xamarin.Forms.Platform.iOS
  • Android – Xamarin.Forms.Platform.Android
  • Windows Runtime – Xamarin.Forms.Platform.WinRT
  • Universal Windows Platform (UWP) – Xamarin.Forms.Platform.UWP

ToView拡張メソッドがネイティブコントロールを NaitiveViewWrapper に変換し、 NaitiveViewWrapperRenderer が汎用的なViewRendererとして働く、という具合ですね。 込み入ったコントロールのために、サイズ決定時に呼ばれるデリゲートなどを渡すことも出来ます。