読者です 読者をやめる 読者になる 読者になる

Xamarin 日本語情報

Xamarin(ザマリン) の代理店だったエクセルソフト田淵のブログです。主に Xamarin に関するエントリーをアップしていきます。(なるべく正しい有益な情報を掲載していきたいと考えていますが、このブログのエントリーは所属組織の公式見解ではありませんのでご注意ください)

de:code 2016 DEV-023 サンプルアプリ解説 - その2(ネイティブの機能を使う)

こんにちは。エクセルソフトの田淵です。

日本マイクロソフトの大型有償技術イベント 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;
            }
        }
    }
}

ドキュメントは

developer.xamarin.com

日本語の情報は Build Insider をご覧ください。

www.buildinsider.net

www.buildinsider.net

Dependency Service

Xamarin Plugin が充実してきたため、使用頻度は減ってきていると思いますが、ネイティブの API を PCL プロジェクトからインターフェース経由で呼び出せるようにする仕組みです。

ドキュメントは こちら をご覧ください。

日本語情報は Build Insider をご覧ください。

www.buildinsider.net

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);
            }
        }
    }
}

で指定したりします。呼び出し方に何種類かありますので、お好みの方法で。

ドキュメントは

developer.xamarin.com

日本語の情報は @ticktackmobile さんのエントリーをご覧ください。

ticktack.hatenablog.jp

Xamarin Plugins

f:id:ytabuchi:20160528144043p:plain:w450

Bait and Switch という仕組みを使用してビルド時に参照ライブラリと実装ライブラリが置き換えられます。

Xamarin の中の人 @atsushieno さんが JXUG でしゃべっていただいた スライド をご覧ください。

Xamarin Plugin を作成したい方はプロジェクトテンプレートが用意されていますので、@ticktackmobile さんのエントリーをご覧ください。

ticktack.hatenablog.jp

続きはその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 も販売してますし、日本で売っていない海外のソフトウェア、開発ツールなどを弊社経由で日本円で購入頂くことも可能です。ご興味あれば 弊社ページ を覗いてみてください。

以上です。