本サイトからスピンオフした姉妹サイトです。Android2015年2月18日iOS/Androidにおけるタップやスワイプなどの各種ジェスチャーを、Xamarin.Formsで処理する方法を解説する。→モバイルアプリでは、タップやスワイプなど、各種のジェスチャーに対応させる必要がある。今回は、Xamarin.Formsで各種のジェスチャーを処理する方法を解説する*1。Studioでも同様の手順で、本稿の内容が実現できることは確認している)。使用しているXamarin.Formsのバージョンは、プロジェクト作成時に利用されている「1.3.1.6296」である。シナリオ最初に、画面にImageビューを配置し、これをタップしたときのイベントを処理する。続いて、Xamarin.Formsで処理できないイベントであるロングタップ(長押し)を、レンダラーの実装によって取り扱う方法を解説する。Portable)]を選択し、名前を「GestureSample」として[OK]ボタンを押す(図1)。共通プロジェクトに「Images」フォルダーを作成し、表示する画像(本稿のサンプルでは「image01.png」)をその中にコピーする。共有プロジェクトに1つの画像ファイルを置く【今回使用した素材画像】プロ生ちゃんサンプルで使用させていただいた画像は、「プロ生」で公開されている壁紙である。「プロ生」では、ガイドラインに従うことで、素材の利用が可能である。アクション]を「埋め込まれたリソース」に変更する(図3)。画面にImageビューを表示するには、App.csファイルを以下のように修正する。{image}};}}}Imageビューを表示するコード(App.cs)Sourceプロパティに画像リソースを指定してImageビューを作成する(1)。共有プロジェクトに置いたリソースは、2のようにImageSource.FromResource()メソッドで取得できる。このとき、リソース名は、「<プロジェクト名>.<フォルダー名>.<画像ファイル名>」である。ビューにはスタックレイアウト(StackLayout)を配置し、そこに画像イメージを表示した(3)。このコードを実行すると次の画面のようになる。タップXamarin.Formsには、TapGestureRecognizerというクラスがあり、これをビューのGestureRecognizersコレクションに追加することで、当該ビューで検出したタップを簡単に取得できる。タップイベントを処理するには、App.csファイルを以下のように修正する。{image}};}}Imageコントロールを配置し、タップイベントを処理するコード(App.cs)最初に、TapGestureRecognizerオブジェクトを作成する(1)。TapGestureRecognizerオブジェクトのTappedイベントで、アラートダイアログを表示する(2)。続いてImageビューのGestureRecognizersコレクションに、作成したTapGestureRecognizerオブジェクトを追加する(3)。このコードを実行して、Imageビューをタップすると次のような画面になる。タップ後の画面(iOS/Android)【コラム】AndroidにおけるNumberOfTapsRequiredのバグTapGestureRecognizerクラスには、検出対象とするタップ回数が指定できるNumberOfTapsRequiredプロパティがある。これを利用すると、次のようなコードで簡単にダブルタップが処理できるはずである。"OK");};ダブルタップを検出するコード実際、iOSで、このコードは正常に動作する。残念ながら、Androidでは、現在、このコードは正常に動作しない。1.3.3.6323でも、修正されていないことを確認している)。ロングタップ実は、TapGestureRecognizerクラスで取得できるイベントは、タップのみである。Xamarin.Formsで、その他のジェスチャーなどに対応するためには、レンダラーを記述するしか方法はない。レンダラーを記述するために必要な最初の作業は、Imageビューを継承した拡張クラス(本稿の例ではExImageクラス)の作成である。GestureSampleプロジェクトに、ExImage.csファイルを追加し、以下のコードのように実装する。EventArgs());}}}}Imageクラスを継承してExImageクラスを作成する(ExImage.cs)ExImageクラスは、Imageクラスを継承して作成する(1)。2では、ロングタップのイベントを定義する。publicでOnLongPressメソッドを定義しておき(3)、実際にコントロールでイベントが発生したときに、これを呼び出すようにする。続いて、この拡張クラスを使用するようにApp.csファイルを修正する。{exImage};}}}拡張したImageクラスを使用して、ロングタップを検出するコード(App.cs)Imageビューは、拡張したExImageクラスを使用するように変更した(1)。拡張クラスで新たに定義したLongPressイベントでアラートを表示するようにした(2)。その他は、タップのときのコードと同じである。レンダラーの実装(iOS)続いて、レンダラーの実装を行う。GestureSample.iOSプロジェクトに、ExImageRenderer.csファイルを追加し、以下のコードを記述する。4}}}iOS用のレンダラー実装コード(ExImageRenderer.cs)1は、レンダラーを記述する場合の定型句である。ExportRenderer属性によって、「ExImageコントロールの描画にはExImageRendererクラスを使用する」と定義している。ImageビューのレンダラークラスはImageRendererであるので、ExImageRendererクラスは、これを継承している(2)。iOSでのロングタップ検出は、UILongPressGestureRecognizerというクラスのインスタンスを生成して(3)、レンダラーのAddGestureRecognizerメソッドでそれをコントロールに登録する(4)という作業になる。詳しく説明すると、3で、UILongPressGestureRecognizerクラスのインスタンスを生成している。そのコンストラクターのメソッド引数に指定しているメソッド(ラムダ式)は、ロングタップを認識(Recognize)すると呼び出される。その中で、先ほど定義したExImageコントロールのOnLongPressメソッドを呼び出している。4では、このUILongPressGestureRecognizerオブジェクトを、コントロール自身に登録している。このコードを実行して、Imageビューをロングタップすると、次のような画面になる。レンダラーの実装(Android)Androidでのロングタップの検出は、iOSと比べるとやや複雑になっている。具体的には、リスナークラスを定義して、これをジャスチャーディテクター経由でコントロール上のイベントにひも付ける作業になる。それでは、順に手順を見ていこう。リスナークラスは、GestureSample.Droidプロジェクトに、MyGestureListener.csファイルを追加し、以下のように実装する。4}}}}リスナークラスのコード(MyGestureListener.cs)リスナークラスは、GestureDetector.SimpleOnGestureListenerクラスを継承して作成する(1)。リスナークラスのExImageプロパティは、外から設定可能な拡張イメージへのポインターである(2)。GestureDetector.SimpleOnGestureListenerクラスは、各種のジェスチャーをハンドルするOnで始まるメソッドを持っており、今回は、ロングタップ時に呼ばれるOnLongPressメソッドをオーバーライドして(3)、そこからExImageオブジェクトのOnLongPressメソッドを呼び出した(4)。続いて、レンダラークラスを定義する。GestureSample.Droidプロジェクトに、ExImageRenderer.csファイルを追加し、以下のように実装する。6}}}Android用のレンダラー実装コード(ExImageRenderer.cs)最初に、先ほど作成したMyGestureListenerクラス(1)と、これを関連付けるために使用するGestureDetectorクラス(2)を定義し、レンダラークラス(ExImageRendererクラス)のコンストラクターで、これらのインスタンスを生成する(3)。リスナークラスのExImageプロパティは、OnElementChangedメソッド内で初期化される(4)。ひも付けは、GenericMotionイベントとTouchイベントに対して行う(56)。実は、ロングタップだけなら、Touchイベントだけでよいのだが、今後の拡張のために、ここでは両方のイベントに同じようにひも付けを行っておく。その他、レンダラーとしての実装は、iOSのものと同じである。このコードを実行して、Imageビューをロングタップすると、次のような画面になる。今回、iOSで使用した、UILongPressGestureRecognizerクラスは、ロングプレスを検出するためのものであるが、これを、UITapGestureRecognizer(タップ)UIPinchGestureRecognizer(ピンチ)UIPanGestureRecognizer(パン・ドラッグ)UISwipeGestureRecognizer(スワイプ)UIRotationGestureRecognizer(ローテイト)などのクラスに置き換えれば、それぞれのジャスチャーを処理できる。)などのメソッドが、オーバーライド可能である。これらを使用することで、各プラットフォームで処理できるイベントは、全てXamarin.Formsでも利用可能となる。まとめ今回は、Xamarin.Formsでタップおよびロングタップを処理する方法を紹介した。レンダラーを実装することで、その他のジェスチャーも全て処理可能であることを示した。各プラットフォームでのジャスチャーなどの扱いは、決して共通化されているわけではない。そのため、Xamarin.Formsから全てを同じように扱うとなると、いろいろと解決すべき問題が残る。この辺が、Xamarin.Formsで、現在タップしか扱われていない理由なのかもしれない。※以下では、本稿の前後を合わせて5回分(第33回~第37回)のみ表示しています。INDEX]を参照してください。Studioのコードエディターのフォントとして設定する方法。きなどを実現する方法を説明する。Xamarin.Formsでタッチイベントを処理するには?(iOS/Androidの各種ジェスチャー対応)iOS/Androidにおけるタップやスワイプなどの各種ジェスチャーを、Xamarin.Formsで処理する方法を解説する。Xamarin.Formsでツールバーアイテムによるメニューを設置するには?PageクラスのToolbarItemsプロパティを使って、画面の上部にツールバー(Android)/ナビゲーションバー(iOS)を表示する方法を解説する。MvvmCrossのプロジェクトをセットアップするには?クロスプラットフォーム開発を支援するXamarin用ライブラリの「MvvmCross」を使ってiOS/Androidアプリ開発を行うためのプロジェクトの作成方法を説明する。機械学習エンジニアを目指す人~初中級者のための技術情報サイトです。「機械学習&AI」「クラウド&ビッグデータ」「IoTデバイス」のネット記事情報を共有中。開発者のためのSlackチーム、作りました:「機械学習&AI」「クラウド&ビッグデータ」「IoTデバイス」のネット記事情報を共有中。2020最適なビューへの切り替えを推奨します:スマートフォン用表示に。