結論から書くと、onTouch
でMotionEvent.ACTION_UP
だけを検知させ、他のイベントはGestureDetector
に丸投げすると実現できる。
Javaサンプルコード
Kotlin使いの方は適宜読み替えてください。
GestureDetectorCompat
にした場合は未検証ですが、同じ挙動になるはずです。
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
private TextView sampleView;
private GestureDetector gestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sampleView = findViewById(R.id.sampleView);
sampleView.setOnTouchListener(this);
gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
// do something
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
// do something
return true;
}
@Override
public void onLongPress(MotionEvent e) {
// do something
super.onLongPress(e);
}
@Override
public boolean onDoubleTap(MotionEvent e) {
// do something
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
// do something
return true;
}
});
}
@Override
public boolean onTouch(View v, MotionEvent e) {
// ここで指が画面から離れたことを検知し、他のイベントはGestureDetectorに委ねる
if (e.getAction() == MotionEvent.ACTION_UP) {
// do something
}
return gestureDetector.onTouchEvent(e);
}
}
補足
コード内の"do something"コメントのところにLog
を仕込むと、動きを確認できます。
GestureDetector
では他にonSingleTapConfirmed
やonFling
などもサポートされていますが、ここでは割愛しています。
詳しく知りたい方は、下記URLから公式ドキュメントをご覧ください。
また、上のコードでは#onTouch should call View#performClick when a click is detected
という警告が出ます。
これについては、stackoverflowに回答がありました。
対処としては、onTouch
内で以下のようにperformClick
を呼んでやると解消できるようです。
if (e.getAction() == MotionEvent.ACTION_UP) {
v.performClick();
// do something
}
ただ、今回の場合はGestureDetector
でクリックイベントに対処するんだから、わざわざperformClick
を呼ぶ意味があるのか?という気がします。
実際、performClick
を呼ばなくても動きは問題なく見えます。
OnTouchListener
とOnClickListener
を併用している場合には考慮が必要になるのかもしれませんが、とりあえずAndroid Studioの警告を消すためにはperformClick
をコールしておくのが無難であるようです。
最後に
記載内容に不備などがありましたら、教えていただけると助かります!