[Android] ImageView をドラッグする

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

Android Studio
2024.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

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


 
ボタンを押すたびに少しづつ画像が斜め下に移動していきます。

  

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

 
これで実行して、画像をドラッグしてみましょう
 
1x1.trans - [Android] ImageView をドラッグする

 

サンプル動画

 

 

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

 

関連:

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

シェアする

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

フォローする