Androidでドラッグアンドドロップ機能の実装
Androidでドラックアンドドロップ
ドラックアンドドロップとは
ドラックアンドドロップとは、アイコンなどを選択し、別の場所に移動させるときに使います。移動している時にアイコンも一緒に動きます。
スマホの場合は、指でタップしたまま移したい場所まで指をスライドさせます。これが実装できるとより直観的に操作することが可能になります。
前提条件
言語はC#でVisualStudioを使用しています。
今回は画面をXMLではなく、Viewクラスを継承したファイルで作成していきます。
ちょっと特殊なつくり方だと思いますが、画像や矩形などの描画が座標指定で描画できるため私はゲーム作成で使っています。
画面の描画はXMLのときと同じくSetContentViewで呼び出すことができます。事前にインスタンス化しておく必要はありますが、、、
SetContentViewで呼び出すとDrawメソッドが呼ばれ、画面が描画されます。
はたしてこの方法で描画している人がいるのかどうか。。。(笑)
実装方法
先ほど説明しましたが、画面の描画はSetContentViewで呼び出します。これを定期的に呼び出したいので、Timerクラスを作成し、そこに記述します。
しかし、単純にTimerクラスで描画しようとしても描画されずに止まってしまうことがあります。そのため、Timerの処理を以下のように記述します。
private Timer timer1; timer = new Timer { Enabled = true; AutoReset = true; Interval = 250; }; timer1.Elapsed += delegate { timer1.stop(); this.RunOnUiThread( () => { UI.PushFinger( FingerX-72, FingerY-72 ); SetContentView( UI ); }); timer1.Start(); }this.RunOnUiThreadが重要となります。この中にSetContentViewを記述しないとうまくいきませんでした。おそらく、Timer用のスレッドでは画面描画用のスレッドに書き込みできないのではないでしょうか。
Timerはこれで準備完了です。ちなみに、UIはViewクラスを継承したファイルのインスタンスで、PushFingerメソッドは今の指の座標を代入するものです。
次に指が画面にタップされたり、移動したり、離れたりを感知するメソッドを作成します。
ActivityクラスのOnTouchEventをオーバーライドして作成します。簡単な記述をMainActivityに以下の記述します。
public override bool OnTouchEvent( MotionEvent e ) { switch (e.Action) { case MotionEventActions.Down: FingerX = e.GetX(); FingerY = e.GetY(); UI.PushFingerData( 1 ); break; case MotionEventActions.Move: FingerX = e.GetX(); FingerY = e.GetY(); break; case MotionEventActions.Up: FingerX = e.GetX(); FingerY = e.GetY(); UI.PushFingerData( 0 ); break; } SetContentView( UI ); }このような感じです。PushFingerDataメソッドはアイコンの識別番号で0のときは描画なしです。そのためタップしたときに0以外の値を入れ、話したときに値を0に戻しています。
最後にUIクラスの一部を記述します。
public override void Draw( Canvas canvas ) { if( FingerData != 0) { canvas.DrawBitmap( Icon, FingerX, FingerY, null ); } }これでBitmapのアイコンを表示し、座標通りに描画されドラッグアンドドロップが実装できます。
これらのコードは最小限のものしか記述していないため、このコードを丸写ししても動かないと思います。あくまで例だと思って下さい。
まとめ
このようにしてAndroidアプリでドラッグアンドドロップを実装することができます。繰り返すタイミングを調整することで滑らかに動くようにもできると思います。
これを応用すればお絵かきアプリなども作成できるかもしれませんね。
実際なぜ私がこの方法で実装したかというと、先日紹介したゲームアプリに必要だったからです。もともとはPC版でWindowsFormAplicationで作成し、OnPaintメソッドで描画する方法を使っていたため、同じように座標指定で描画できるViewクラスの継承を利用しました。
そのためスクロールなども自分で作成しないといけないため大変なんですけどね
今回のテーマであるドラッグアンドドロップだけでなくRunOnUiThreadはXMLでも利用するため参考になれば幸いです!!
今回はこの辺で、ではまた!