SimpleOnScaleGestureListener と SimpleOnGestureListener を一緒に使用するアプリがあります。ピンチ ズームを行うたびに、期待どおりの onScale が得られますが、離陸すると、ピンチ ズームの開始位置から開始位置があり、ピンチ ズームの終了位置から終了位置がある奇妙な onScroll が表示されます。私の質問は、偽の onScroll を防ぐことはできますか?
コードは次のとおりです。
@Override
public boolean onTouchEvent(MotionEvent event) {
// Log every event.
Log.d(TAG, Here.at() + String.format("Event: %d, Time: %d X: %f, Y: %f",
event.getAction(),
event.getEventTime(),
event.getX(),
event.getY()
));
boolean handled = mScaleDetector.onTouchEvent(event); // This appears to ALWAYS return true (online reference indicated that's what the Android code does).
handled |= mDetector.onTouchEvent(event);
handled |= super.onTouchEvent(event);
return handled;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
// This is required. If absent, the scale gesture never starts.
Log.d(TAG, "In onScaleBegin");
mIgnoreNextDrag = true;
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
Log.d(TAG, "In onScale");
mTimeScale.doScale(detector.getScaleFactor(), detector.getFocusY());
invalidate();
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
Log.d(TAG, "In onScaleEnd");
}
}
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent me1, MotionEvent me2, float distanceX, float distanceY) {
Log.d(TAG, String.format("Motion Event 1: %d, Time: %d X: %f, Y: %f",
me1.getAction(),
me1.getEventTime(),
me1.getX(),
me1.getY()
));
Log.d(TAG, String.format("Event 2: %d, Time: %d X: %f, Y: %f",
me2.getAction(),
me2.getEventTime(),
me2.getX(),
me2.getY()
));
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent me) {
// Do tap processing.
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// TODO: Future feature.
return true;
}
@Override
public boolean onDown(MotionEvent e) {
// This is required. If absent, the scroll gesture never starts.
return true;
}
}
LogCat は次のとおりです。
13:06:05.885: D/my-tag(4140): In View.onTouchEvent, Event: 0, Time: 183279420 X: 171.761444, Y: 918.160767
13:06:05.895: D/my-tag(4140): In View.onTouchEvent, Event: 261, Time: 183279420 X: 171.761444, Y: 918.160767
13:06:05.895: D/my-tag(4140): In onScaleBegin
13:06:05.895: I/ScaleGestureDetector(4140): TwScaleGestureDetector
13:06:05.915: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279458 X: 171.761444, Y: 908.474365
13:06:05.915: D/my-tag(4140): In onScale
13:06:06.015: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279542 X: 174.964783, Y: 857.584717
13:06:06.015: D/my-tag(4140): In onScale
13:06:06.105: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279641 X: 232.242096, Y: 731.365662
13:06:06.105: D/my-tag(4140): In onScale
13:06:06.215: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279740 X: 313.564514, Y: 595.412964
13:06:06.215: D/my-tag(4140): In onScale
13:06:06.225: D/my-tag(4140): In View.onTouchEvent, Event: 6, Time: 183279751 X: 313.564514, Y: 595.412964
13:06:06.225: D/my-tag(4140): In onScaleEnd
13:06:06.245: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279774 X: 333.316528, Y: 487.607422
13:06:06.245: D/my-tag(4140): In onScroll, me1: 0, Time: 183279420 X: 171.761444, Y: 918.160767
13:06:06.245: D/my-tag(4140): In onScroll, me2 2: 2, Time: 183279774 X: 333.316528, Y: 487.607422
13:06:06.255: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279784 X: 331.539551, Y: 488.496460
13:06:06.265: D/my-tag(4140): In onScroll, me1: 0, Time: 183279420 X: 171.761444, Y: 918.160767
13:06:06.265: D/my-tag(4140): In onScroll, me2 2: 2, Time: 183279784 X: 331.539551, Y: 488.496460
13:06:06.275: D/my-tag(4140): In View.onTouchEvent, Event: 1, Time: 183279794 X: 331.539551, Y: 488.496460
最初のイベントは、最初の指が下にあること (0 = ACTION_DOWN)、次に 2 番目の指が下にあること (261 = ACTION_POINTER_2_DOWN) であることがわかります。次に、onScaleBegin 呼び出しからのログ エントリと、(私のコードではなく) スケール ジェスチャ検出器自体からのログが表示されます。この時点で、スケール ジェスチャが開始されたと安全に想定できると思います。これはまさに予想通りです。
この後に 4 つの移動イベント (2 = ACTION_MOVE) が続き、それぞれの直後に onScale からのログ エントリが続きます。これはまだ予想通りです。
次に、ポインタ アップ イベント (6 = ACTION_POINTER_UP) に続いて、onScaleEnd からのログ エントリが表示されますが、それでも AOK! (262 ではなく 6 であることに注意してください。これは、指を置いたのと同じ順序で指を持ち上げたため、ポインター 2 ではなくポインター 1 が最初に持ち上げられたためです。)
今奇妙なビット。
SimpleOnGestureListener の onScroll によって取得される移動イベントが表示されます。最初のパラメーター me1 は、スケール ジェスチャが開始される前の最初のダウン イベントの x 座標と y 座標を持ちます。2 番目のパラメーター me2 は、スケール ジェスチャが停止した後の位置を明らかに反映する座標を持ちます。
この例では、実際にはスクロール ジェスチャとして解釈される 2 番目の移動イベントがあり、ここでも原点がプリスケールされています。上記のコードを使用すると、ピンチ ズーム後にスクロール イベントが 1 回、2 回、またはまったく発生しません。
(LogCat を終了するには、2 番目の指の最終アップ イベント (1 = ACTION_UP) を実行し、ログを停止します。)
だから私はそれを間違っていますか?SimpleOnScaleGestureListener が isInProgress から false を返す場合にのみ、SimpleOnGestureListener を呼び出してみましたが、喜びはありません。
何か案は?
事前に感謝します。また、長年にわたってこのサイトから得た膨大な量の情報について、コミュニティのすべての人に感謝します!