本サイトからスピンオフした姉妹サイトです。Xamarin2015年5月27日MvvmCrossでのiOS/Androidアプリ開発において、バインディングする値を変換できるカスタムコンバーターの使い方を説明する。→MvvmCrossのiOS/Androidアプリ開発では、カスタムコンバーターを用いることでバインディングする値を変換できる。今回は、そのカスタムコンバーターを作成し、iOS/Android各プラットフォームから、それを利用する方法を解説する*1。Studioでも同様の手順で、本稿の内容が実現できることは確認している)。Converter(以下、コンバーター)とは、MvvmCrossの機能の一つで、プロパティバインディング時に、その値を変換する仕組みである。ViewModelプロパティからViewプロパティへの変換と、ViewプロパティからViewModelプロパティへの変換の双方向に対応している。コンバーターは、「ViewModelの論理的な値」と「Viewへ表示したい値」に差があるときに活躍する。ViewModelにコンテンツの投稿時刻をDateTime型のプロパティとして保持しておき、Viewではstringプロパティとして“12:01”のような“時:分”形式の文字列を受け取る場合などである。時:分)などの表示へ変更することもできる。コンバーターを利用するプロジェクトは、基本的に図1のようになる。コンバーターの所属するプロジェクト図1の通り、コンバーターはCoreプロジェクトに実装することも、TouchプロジェクトとDroidプロジェクト、それぞれで実装することもできる。同じデータであっても、プラットフォームごとに異なる表示をさせたり、プラットフォームごとの画像リソースを表示したりするといった対応が可能となる。ViewModelの値を変換してViewへ渡せる仕組みであるため、コンバーターは画面作成時に活躍するが、パフォーマンスがシビアな局面では注意が必要だ。iOSのUITableViewやAndroidのListViewなどのリスト形式のViewは、リストアイテムとなるViewが再利用されるため、スクロールするたびにバインディングが発生する。コンバーターはバインディングの都度、実行されるため、リストスクロールの負荷が高くなることがある。実装方針それではコンバーターのサンプルを作成してみよう。Coreプロジェクトへ実装する(プラットフォーム間で共通の)コンバーターと、プラットフォームごとに実装するコンバーターを順に実装する。はじめに、入力された文字数をカウントするTextCountコンバーターを、Coreプロジェクトに実装する。次に、入力された文字数が10文字以上であれば色付きで文字数を表示するCountColorコンバーターを、プラットフォームごとのプロジェクトで実装する。「Tips:MvvmCrossのプロジェクトをセットアップするには?」の手順に従い、MvvmCrossプロジェクトを作成する。ソリューション名は「CrossConverterSample」と設定する。Coreプロジェクトの実装FirstViewModelクラスは、プロジェクト作成時にあらかじめ実装されているHelloプロパティを使用するため、変更の必要はない。コンバータークラスを作成する。CrossConverterSample.CoreプロジェクトのルートディレクトリへConvertersディレクトリを作成し、その下へMvxTextCountConverter.csファイルを作成する(図2)。MvxTextCountConverter.csの構成MvxTextCountConverterクラスは次のように実装する。count);}}}プラットフォーム間で共通のコンバーター(MvxTextCountConverter.cs)コンバータークラスはMvvmCrossに用意されているIMvxValueConverterインターフェースを実装する。Convertメソッドにより、ViewModelからViewへ値が渡されるときのコンバート処理を実装し、ConvertBackメソッドにより、ViewからViewModelへ値が渡されるときのコンバート処理を実装する。IMvxValueConverterインターフェースではConvertメソッドとConvertBackメソッドの引数はobject型であり、メソッド内でキャストが必要となる。バインドされる型が限定されている場合には、MvxValueConverterクラスを型クラス指定ありで継承することで引数の型を限定できる。今回は、string型からstring型へのコンバーターとして実装している。MvxTextCountConverterはViewModelからViewへの一方向のバインディングであるため、Convertメソッドのみ実装している。count"のフォーマットで返す。コンバータークラス名についてMvvmCrossはアプリ起動時に、IMvxValueConverterを継承したクラスをコンバータークラスとして列挙する。このとき、コンバータークラス名は次のようなものとなる。TextCountTextCountValueConverterTextCountConverterMvxTextCountValueConverterMvxTextCountConverterこれらのクラスは全て「TextCount」の名前でコンバーターとして登録される。コンバータークラスはCoreプロジェクトのものとプラットフォームごとのプロジェクトのものとで同じ名前空間で識別される。同一の名前のコンバータークラスが複数存在した場合には、最後に登録されたコンバータークラスが有効となる。Touchプロジェクトの実装Touchプロジェクトではレイアウトを編集し、コンバーターを使用したバインディングを定義する。2set.Apply();}}}Touchプロジェクトのレイアウトを作成する(FirstView.cs)1で文字数を表示するラベルを画面へ追加する。2でlabelCountラベルへ、HelloプロパティをTextCountコンバーターを使ってバインドする。WithConversionメソッドでコンバーターを指定する。Helloプロパティが更新されたとき、CoreプロジェクトのMvxTextCountConverterクラスが値を受け取り、その文字数をlabelCountラベルへ表示する。Droidプロジェクトの実装Droidプロジェクトも同様にレイアウトを編集し、コンバーターを使用してバインディングを定義する。[CrossConverterSample.Droid]プロジェクトの[Resources]-[layout]ディレクトリにある[FirstView.axml]ファイルを開き、その[Source]を次のように修正する。/></LinearLayout>Droidプロジェクトのレイアウトを作成する(FirstView.axml)1で文字数を表示するTextViewを作成し、TextCountコンバーターを設定してHelloプロパティをバインディングしている。XML(.axml)ファイルではMvxBind属性でTextCount(Hello)のようにコンバーターとその引数となるプロパティを指定する。アプリケーションの実行ここでアプリケーションを実行すると、次のように表示される。テキストを編集すると、その文字数をカウントして画面へ表示する。次に、プラットフォームごとに異なるコンバーターを実装してみよう。今回はCoreプロジェクトを修正する必要はなく、TouchプロジェクトとDroidプロジェクトのみ追加で実装する。Touchプロジェクトの実装まず、Touchプロジェクト用のコンバータークラスを作成する。CrossConverterSample.TouchプロジェクトのルートディレクトリにConvertersディレクトリを作成し、その下へMvxCountColorConverter.csファイルを作成する(図4)。MvxCountColorConverter.csの構成MvxCountColorConverterクラスは次のように実装する。UIColor.White;}}}Touchプロジェクト用のコンバーター実装(MvxCountColorConverter.cs)クラス名の命名やMvxValueConverterクラスの継承など、実装方法はTextCountコンバーターとほとんど変わりはない。CountColorコンバーターは与えられたプロパティの文字数が10以上のときUIColor.Redを返し、10未満であればUIColor.Whiteを返す。CountColorコンバーターは変換後にUIColorを返している。UIColorクラスはTouchプロジェクトからのみ参照できるクラスであるため、MvxCountColorConverterクラスをCoreプロジェクトのコンバーターとして実装することはできない。次にTouchプロジェクトのバインディングを修正する。[CrossConverterSample.Touch]プロジェクト-[Views]ディレクトリ-[FirstView.cs]ファイルを次のように修正する。1この一行を追加set.Apply();}}}Touchプロジェクト用のバインディング設定(FirstView.cs)1の一行を追加する。labelCountラベルのBackgroundColorプロパティへ、CountColorコンバーターを使用してHelloプロパティをバインディングしている。CountColorコンバーターはHelloプロパティの文字数をカウントしてUIColorを返すため、文字数によってlabelCoutラベルの背景色が変化する。次に、Droidプロジェクトのコンバーターを作成しよう。CrossConverterSample.DroidプロジェクトのルートディレクトリへConvertersディレクトリを作成し、その下へMvxCountColorConverter.csファイルを作成する(図5)。MvxCountColorConverter.csの構成MvxCountColorConverterクラスは次のように実装する。(Color.Black);}}}Droidプロジェクト用のコンバーター実装(MvxCountColorConverter.cs)実装方法もロジックも、TouchプロジェクトのMvxCountColorConverterクラスと同様であるが、変換後の値としてColorDrawableインスタンスを返す点が異なる。DroidプロジェクトでバインディングするViewのプロパティはTextViewクラスのBackgroudプロパティであり、BackgroundプロパティはDrawable型であるため、これにそろえた返り値となる。DroidプロジェクトのCountColor実装は、渡されたプロパティの文字数が10以上であればColor.RedのColorDrawableインスタンスを返し、10未満であればColor.BlackのColorDrawableインスタンスを返す動作となる。CountColorコンバーターはTouchプロジェクトのコンバーターと名前が被っているが、TouchプロジェクトとDroidプロジェクトは依存関係がなく、どちらのプラットフォーム向けのビルドをした場合でも二つのコンバータークラスは衝突しない。次に、Droidプロジェクトのバインディングを修正する。[CrossConverterSample.Droid]プロジェクトの[Resources]-[layout]ディレクトリにある[FirstView.axml]ファイルを次のように修正する。/></LinearLayout>Droidプロジェクト用のバインディング設定(FirstView.axml)1のMvxBind属性の値を修正する。TextViewのBackgroundプロパティへ、CountColorコンバーターを使いHelloプロパティをバインディングしている。この修正により、入力された文字数によって文字数表示用のTextViewの背景色が変化する。アプリの実行これで全ての実装が完了した。アプリを実行すると以下のように表示される。テキストを編集すると文字数がカウントされ、文字数が10以上のとき、文字数表示の背景色が赤色となる。コンバーターをプラットフォームごとに実装したため、iOSアプリとAndroidアプリとでは10文字未満の場合に異なった背景色設定されている。背景色変化ありのアプリ動作(iOS/Android)【コラム】MvvmCrossで提供されているコンバーターMvvmCrossには、MvvmCrossプラグイン形式で複数のコンバーターが提供されている。いずれも使いやすいコンバーターであるため、確認しておこう。MvxVisibilityValueConverterクラスとMvxInvertedVisibilityValueConverterクラスは、プロパティの値によってViewの表示/非表示の状態を切り替えるコンバーターである。以下の例に示すように、「Visibility」ターゲットを指定することで、iOSアプリではUViewクラスのHiddenプロパティを、AndroidアプリではViewクラスのVisibilityプロパティを設定する動作となる。vm.VMProperty).WithConversion("Visibility");Visibilityコンバーターを用いたバインディング例MvxVisibilityValueConverterクラスは以下の表に示すように柔軟に判定を行う。MvxInvertedVisibilityValueConverterクラスは以下の条件を反転させたコンバーターである。Pluginをインストールすることで利用できる。MvxNativeColorValueConverterクラスはMvxColorクラスをプラットフォームごとの色表現(iOSならUIColor、Androidならint値)へ変換するコンバーターである。MvxColorクラスはCoreプロジェクトで共通にプラットフォームの色を扱うためのクラスとして用意されている。MvxRGBAValueConverterクラスはRGBの文字列による色表現を、それぞれのプラットフォームの色表現へ変換するコンバーターである。MvxRGBAValueConverterクラスは次の文字列表現をパース可能である。“RRGGBBAA”または“#RRGGBBAA”形式MvxRGBIntColorConverterクラスはint型による色表現を、それぞれのプラットフォームの色表現へ変換するコンバーターである。Pluginをインストールすることで利用できる。※以下では、本稿の前後を合わせて5回分(第49回~第53回)のみ表示しています。INDEX]を参照してください。MvvmCrossでAndroidの画面の再生成に対応するには?Androidアプリでは別アプリ移動時に画面が破棄され、アプリ再表示時に画面が復元される場合がある。この画面の再生成を、MvxViewModelのライフサイクルメソッドにより行う方法を説明する。Xamarin.Formsでローカルデータベースを使用するには?アプリを終了して再起動したときに、ユーザーデータを復活させたい場合、ローカルやクラウドにデータを保存することになる。その一つの方法として、SQLite.Netを使ってローカルDBに保存する方法を説明する。MvvmCrossでカスタムコンバーターを作成するには?MvvmCrossでのiOS/Androidアプリ開発において、バインディングする値を変換できるカスタムコンバーターの使い方を説明する。Xamarin.FormsでTwitterクライアントを作成するには?TwitterのAPIを扱えるライブラリであるCoreTweetを使用して、Twitterデータを検索するアプリを作成。CoreTweetの導入と、検索したテキストの表示までを紹介する。MvvmCrossでWebBrowserプラグインを使用するには?WebBrowserプラグインを追加・利用する例を通じて、MvvmCrossでのiOS/Androidアプリ開発におけるMvvmCrossプラグインの基本的な使い方を説明する。機械学習エンジニアを目指す人~初中級者のための技術情報サイトです。「機械学習&AI」「クラウド&ビッグデータ」「IoTデバイス」のネット記事情報を共有中。開発者のためのSlackチーム、作りました:「機械学習&AI」「クラウド&ビッグデータ」「IoTデバイス」のネット記事情報を共有中。2020最適なビューへの切り替えを推奨します:スマートフォン用表示に。