[Android] ImageView をドラッグする

アイコン画像をドラッグしてごみ箱に入れるなどの、ドラッグをAndroidでやる場合にonTouchを使います。タッチした指の動きに合わせてlayoutメソッドを使い画像などを移動させ、あたかもドラッグしているようにできます。

Android Studio
2021.1.1




画像をドラッグさせる

 
画像をドラッグさせるために使う仕組みは大きく以下の2つを使います

1. layout(int, int, int, int)

  • Viewのメソッドで、上下左右の位置を変えることでViewを移動

2. onTouch

  • ムーブアクションを取得してそれと同じ座標に画像を配置

1x1.trans - [Android] ImageView をドラッグする


 
 

layout メソッドを使って画像を移動

 
例えば、このような画像bag.pngを用意してdrawableに配置します。
 
1x1.trans - [Android] ImageView をドラッグする


 
あるいは \res\mipmap 以下にあるDroid君のアイコン画像をコピーして代用もできます。
1x1.trans - [Android] ImageView をドラッグする

Viewクラスのメソッドであるlayoutは、引数としてViewの left, top, right, bottom を設定できます。
 


 
View自体のサイズを固定とするとx方向、y方向の移動量と画像の縦横幅を加算することでViewを移動させられます。
 


 
これをImageViewに当てはめて画像を移動することを確認してみます。
 
MainActivity.java


 
activity_main.xml


 
リソースです
strings.xml


 

 
ボタンを押すたびに少しづつ画像が斜め下に移動していきます。
 
Buttonタップを使って画像の移動ができるようになりました。
次は画像をつかんでドラッグをタッチイベントを使って実装します。

 

onTouchでタッチイベントを拾う

 
タッチイベントを扱うものとして


があります

似たものとしては
onTouchEvent(MotionEvent motionEvent)

がありますが、これはActivityの画面全体でのタッチイベントを拾う時に使います

Activity にOnTouchListener を実装しますので


の設定が必要です

一方onTouchは例えばImageViewにリスナーを設定します


 
ところがこれはビルドエラーにはなりませんが警告が出てきます。
(このImageViewにリスナーを設定でできない事はないのですが…)
 
1x1.trans - [Android] ImageView をドラッグする
 
“Custom View has onTouchListner called on it but doesn’t override performClick”
performClickをoverrideしないといけないという警告です。これは簡単にはできないのでImageViewを継承したカスタムのCustomImageViewクラスを作ってoverrideします。
 


 
onTouch(View v, MotionEvent event):
Viewのタッチにより以下の状態を取得できます。

ここでタッチした位置とドラッグしていく位置を getRawX(), getRawY() で取得して
その移動量をViewにのlayoutを使って反映させることで、Viewがつかまれてドラッグされたようにしていきます。

 

サンプルコード

 
CustomImageViewクラスをImageViewを継承して作り、そのインスタンスにonTuchイベントのリスナーを実装します。

MainActivity.java


 
ImageViewを継承させるのですが、


を使うように推奨されますのでAppCompatImageViewを継承して、念願のperformClick()をoverrideします。新しくCustomImageView.javaのファイルを作成

CustomImageView.java


 

ConstraintLayoutは軽い?
このサンプルコードでは移動座標を TextView で表示していますが、LinearLayoutやRelativeLayoutのレイアウトを使うとTextViewを表示させないケースでは問題ないのですが、TextViewを表示や、何か別の作業をこのACTION_MOVEで行うとドラッグが重くなります。これはConstraintLayoutを使とうまくいきます。ConstraintLayoutのほうが処理が軽いからだと思われます。

 
また、カスタムImageViewなので
com.example.xxx.CustomImageView
のようにpackage name + class name で作成します。(そのままコピペしないように)

activity_main.xml


 
リソース
strings.xml


 

 

サンプル動画

 

 
logには画像をドラッグした座標が記録されています
logcat


 

関連:

References:
layout(int, int, int, int) | Android Developers
View.OnTouchListener | Android Developers
MotionEvent | Android Developers

シェアする

  • このエントリーをはてなブックマークに追加

フォローする