なお、タッチ/フリック or ピンチのジェスチャーそのものの実装方法は以下の記事をご覧ください。
=== 目次 ===
タッチ/フリック + ピンチのジェスチャーを同時に実装する方法
タッチ/フリック + ピンチのジェスチャーを同時に実装するにはタッチ/フリック および ピンチ のジェスチャーオブジェクトをそれぞれ取得し、それぞれにタッチイベントを渡してあげるだけです。以下、サンプルコードです。
public class GestureTestActivity extends AppCompatActivity implements GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener {
GestureDetectorCompat mGestureDetector;
ScaleGestureDetector mScaleDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gesture_test);
mGestureDetector = new GestureDetectorCompat(this, this);
mScaleDetector = new ScaleGestureDetector(this, this);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return event.getPointerCount() > 1 ? mScaleDetector.onTouchEvent(event) : mGestureDetector.onTouchEvent(event);
}
@Override
public boolean onDown(MotionEvent motionEvent) {
//タップ時(タップした瞬間)
Log.d("MY_LOG_TAG", "onDown");
return true;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
//タップ時(すこしの間タップした場合)
Log.d("MY_LOG_TAG", "onShowPress");
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
//タップしてすぐに離したとき
Log.d("MY_LOG_TAG", "onSingleTapUp");
return true;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
//スクロール中
Log.d("MY_LOG_TAG", "onScroll");
return true;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
//ロングタップ時
Log.d("MY_LOG_TAG", "onLongPress");
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float v, float v1) {
//フリック後
Log.d("MY_LOG_TAG", "onFling");
double DiffX = e2.getX() - e1.getX();
double DiffY = e2.getY() - e1.getY();
double theta = Math.atan(DiffY / DiffX) / Math.PI * 180.0;
if(theta > -45 && theta < 45) {
if(DiffX < 0) {
//Right flick
} else {
//Left flick
}
} else {
if (DiffY < 0) {
//Up flick
} else {
//Down flick
}
}
return true;
}
@Override
public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
//ピンチ動作中
Log.d("MY_LOG_TAG", "onScale");
if(scaleGestureDetector.getScaleFactor() > 1) {
//拡大動作
Log.d("MY_LOG_TAG", "拡大");
} else {
//縮小動作
Log.d("MY_LOG_TAG", "縮小");
}
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) {
//ピンチ動作開始
Log.d("MY_LOG_TAG", "onScaleBegin");
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) {
//ピンチ動作終了
Log.d("MY_LOG_TAG", "onScaleEnd");
}
}
サンプルコードの解説
まず、タッチ/フリック および ピンチ のジェスチャーオブジェクトをそれぞれ取得します。 GestureDetectorCompat mGestureDetector;
ScaleGestureDetector mScaleDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gesture_test);
mGestureDetector = new GestureDetectorCompat(this, this);
mScaleDetector = new ScaleGestureDetector(this, this);
}
あとはそれぞれのゲスチャーオブジェクトにタッチイベントを渡してあげるだけです。
@Override
public boolean onTouchEvent(MotionEvent event) {
return event.getPointerCount() > 1 ? mScaleDetector.onTouchEvent(event) : mGestureDetector.onTouchEvent(event);
}
getPointerCountでタッチの指の数を判定し、ピンチ or タッチ/フリック のジェスチャーオブジェクトにそれぞれタッチイベントを渡してやります。
※StackOverFlowなどには以下のように書かれていることが多いですが、個人的には上記のようにタッチの指の数を判定した方がなんとなく安定している気がします(すみません。体感で、明確な根拠なしです)。
return mScaleDetector.onTouchEvent(event) | mGestureDetector.onTouchEvent(event);
まとめ
Androidアプリ開発において、タッチ/フリック + ピンチのジェスチャーを同時に実装する方法を紹介しました。なお、タッチ/フリック or ピンチのジェスチャーそのものの実装方法は以下の記事をご覧ください。