Xamarin.Formsに触れてみた話
はじめに
この記事は [初心者さん・学生さん大歓迎!] Xamarin その1 Advent Calendar 2017 - Qiita の一日目の記事です。
なんとなく気になりつつも触れていなかった Xamarin に触れてみた、という内容です。
なお Xamarin には Android や iOS の薄いラッパーである Xamarin.Android / Xamarin.iOS もありますが、
今回は Xamarin.Forms を試してみることにしました。
理由としては、同じように C# で書けてマルチプラットフォームに対応する Unity との使い分けができると良いな、と思ったためです。
Xamarinプログラミング入門をベースに自分の興味に任せて試した内容をまとめてみたいと思います。
準備
まずは準備から。 Visual Studio は 2017.15.4.4 Community Edition を使っています。
インストールは Visual Studio 本体のインストール時か、メニューの ツール > ツールと機能を取得 から、
.Netによるモバイル開発 にチェックを入れると可能です。
簡単ですね。
Xamarin Live Playerが有効にならない
Xamarin には Xamarin Live Player という機能があり、
Android や iPhone に同名のアプリをインストールして Visual Studio とリンクしておくと、
同一ネットワークにつながっている場合はUSBケーブルでPCに接続しなくても実機でのデバッグを行うことができます。
(iPhone は Mac が必要)
使い方は例えば Android なら、プロジェクトを Android に切り替えて、
デバイスを選択するところから Xamarin Live Player を選択・・・
できませんでした/(^o^)\
Visual Studio のバージョンは問題ないし、 Xamarin も最新といっているし・・・
と思っていたら、公式サイトに載っていました。
どうやらデフォルトでは有効になっていないらしく、
ツール > オプション > Xamarin > その他 から、 Xamarin Live Playerを有効にする にチェックを入れる必要があるそうです。
ちゃんと説明は読みましょう、というお話でしたorz
なお有効にしたあと、テザリング環境でも試してみましたが、
Androidについてはテザリング環境でも問題なく接続できました。
確認したい端末が複数台ある場合など、結構便利なのではないでしょうか。
デフォルトのプロジェクトを見てみる
テンプレートを Blank App 、 Code Sharing Strategy を PCL にして Xamarin プロジェクトを作成すると、
以下の4つのプロジェクトを持つソリューションが生成されます。
(プロジェクト名は XamarinSample としました)
View は XamarinSample (移植可能) のものを使います。
が、ほかのプロジェクトを見てみると、それぞれ MainPage.xaml(UWP) や MainActivity.cs(Android) など、
スタートアップやメインページの表示に関わりそうなファイルが見つかります。
とりわけ気になったのが UWP 。
MainPage.xaml と App.xaml って、 XamarinSample (移植可能) と一緒じゃないのという。
試しに UWP の MainPage.xaml にボタンなどを追加してみましたが、
少なくともデフォルトでは反映されませんでした。
また、 MainPage.xaml を削除するとエラーが発生しました。
基本的に各プロジェクトのコードはスタートアップのために存在するもののようで、
UWP については MainPage.xaml.cs や App.xaml.cs のコードビハインドが必要なので空の Xaml ファイルがある、
ということのようです。
xamlとxaml.csについて
XamarinSample (移植可能) の MainPage.xaml と MainPage.xaml.cs ですが、
デフォルトではプロジェクト直下にあります。
これを View というディレクトリを作ってその中に移動し、
MainPage.xaml.cs の namespace を合わせて XamarinSample.View のように変更してやると、エラーになります。
これは MainPage.xaml や App.xaml.cs で MainPageクラスを呼んでいるためで、
合わせて変更してあげる必要があります。
MainPage.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="XamarinSample.View.MainPage"> ~省略~ < /ContentPage>
App.xaml.cs
~省略~ public App() { InitializeComponent(); MainPage = new XamarinSample.View.MainPage(); } ~省略~
イベントとナビゲーションの追加
それでは、画面にボタンを追加して別のページに遷移する、というのを試してみたいと思います。
まずは SubPageOne.xaml というページを追加しておきます。
ナビゲーション
Xamarin.Forms では、 NavigationPage を使用することで、
比較的簡単にページ遷移が実装できるようになります。
NavigationPage を使用するためには、
XamarinSample (移植可能) の App.xaml.cs を変更する必要があります。
Before
~省略~ public App() { InitializeComponent(); MainPage = new XamarinSample.View.MainPage(); } ~省略~
After
~省略~ public App() { InitializeComponent(); MainPage = new NavigationPage(new XamarinSample.View.MainPage()); } ~省略~
あとは下記のように Navigation.PushAsync を使えばOKです。 (なお遷移後のページには戻るボタンが自動で表示されます)
MainPage.xaml.cs
using System; using Xamarin.Forms; namespace XamarinSample.View { public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } async void OpenSubPageOneButtonClicked(object sender, EventArgs e) { // 遷移後のページ(SubPageOne.xaml.cs を指定する). await Navigation.PushAsync(new SubPageOne()); } } }
遷移前
遷移後
イベント
MainPage.xaml にボタンを追加して、 MainPage.xaml.cs の OpenSubPageOneButtonClicked をイベント関数としてセットします。
MainPage.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="XamarinSample.View.MainPage"> < ContentPage.Content> < AbsoluteLayout BackgroundColor="Yellow"> < Button AbsoluteLayout.LayoutBounds="20,20,200,30" Clicked="OpenSubPageOneButtonClicked" BackgroundColor="#0078d7">SubPage1< /Button> < /AbsoluteLayout> < /ContentPage.Content> < /ContentPage>
プラットフォーム固有のクラスを呼ぶ
さて、基本的には各プラットフォーム共通の処理を XamarinSample (移植可能) に追加していくわけですが、
中にはプラットフォームごとに処理を分ける必要がある場合もあります。
その場合の方法はいくつかあるようですが、
今回は DependencyService を使うことにしました。
XamarinSample (移植可能) にインターフェースを作っておき、
各プラットフォームのプロジェクトにそのインターフェースを継承したクラスを作り、
そこで固有の処理を書きます。
で、それを DependencyService を使って実行時に該当プラットフォームのクラスを呼ぶ、
という流れのようです。
ICalc.cs
namespace XamarinSample { public interface ICalc { float Calc(float currentValue, float calcValue); } }
呼ばれる側
Subtraction.cs (Androidプロジェクトに作成)
using Xamarin.Forms; using XamarinSample.Droid; // DependencyServiceで呼べるようにする. [assembly: Dependency(typeof(Subtraction))] namespace XamarinSample.Droid { public class Subtraction : ICalc { public float Calc(float currentValue, float calcValue) { return 4; } } }
Subtraction.cs (UWPプロジェクトに作成)
using Xamarin.Forms; using XamarinSample.UWP; // DependencyServiceで呼べるようにする. [assembly: Dependency(typeof(Subtraction))] namespace XamarinSample.UWP { public class Subtraction : ICalc { public float Calc(float currentValue, float calcValue) { return 2; } } }
呼び出す側
SubPageOne.xaml.cs
using System.Diagnostics; using Xamarin.Forms; using XamarinSample.ViewModel; namespace XamarinSample.View { public partial class SubPageOne : ContentPage { public SubPageOne() { InitializeComponent(); var subtraction = DependencyService.Get(); Debug.WriteLine(subtraction.Calc(0, 1).ToString()); } } }
これで、Android で実行した場合は 4 が、Windows で実行した場合は 2 が返ってきます。 #if ~ で切り分けるよりシンプルで良いですね。
出力する
apk ファイル (Android) や ipa ファイルとしてアプリを書き出したい場合、 ソリューションエクスプローラーのそれぞれのプロジェクト上で 右クリック -> アーカイブ をクリックすればOKのようです。
UWP は HockeyApp または ストア > アプリパッケージの作成 から。
また Windows で iOS を出力する場合は、 Mac の Xcode に接続されている必要があります。
なおストア配信時の設定は下記のような情報を参考に。
- Xamarin.Android で作成したアプリケーションの配布方法 - Xamarin : XLsoft エクセルソフト
- Xamarin.iOS で作成したアプリケーションの App Store への配布方法 - Xamarin : XLsoft エクセルソフト
おわりに
同じように C# でコードを書き、マルチプラットフォームにアプリを作成できる Unity とはずいぶん違うのだなぁ、というのが率直な感想です。
C#7が使えたり (Unity は Experimental な機能を On にしても C#6 までの対応 )、
独自のお作法ももちろんあるのでしょうが、 WPF など普通の? C# に近い印象を受けました。
もちろん Unity が悪いって話ではなく、ただ違うという話ですよ。念のため。
Xamarin.Forms の Xaml 用 GUI エディタがない(っぽい)、
何かいじるとエラーが (大抵実行には問題がなく、エラーの出たプロジェクトをクリーン・リビルドすると直るのですが)、
とまだ発展途上なところも見受けられます。
が、すぐ改善されるだろうと思いますし、できれば自分もそれに寄与できればなぁ、とも思いました。
最後に、今回作ったサンプルは、(ボタン位置などめちゃくちゃですが)黄色をベースに作っていました。
その理由は。。。
♪ We all live in a yellow Xamarin, yellow Xamarin, yellow Xamarin ♫
https://www.youtube.com/watch?v=vefJAtG-ZKI
・・・おあとがよろしいようで。
明日は gnk263 さんです。よろしくお願いいたします(..)_
参照
- Xamarinプログラミング入門
- Xamarin.Forms 入門ガイド - Xamarin : XLsoft エクセルソフト
- Xamarin Live Player Setup - Xamarin
- Creating Mobile Apps with Xamarin.Forms Book First Edition - Xamarin
- Xamarin.Formsからプラットフォーム固有の機能を利用するには?(DependencyService利用) - Build Insider
- ios - Xamarin.iOS及びXamarin.AndroidのclassをPCLから参照する方法 - スタック・オーバーフロー
- Creating Mobile Apps with Xamarin.Forms Book First Edition - Xamarin
- Xamarin.Android で作成したアプリケーションの配布方法 - Xamarin : XLsoft エクセルソフト
- Xamarin.iOS で作成したアプリケーションの App Store への配布方法 - Xamarin : XLsoft エクセルソフト