かなりの量のズームに関する質問を読み、ここで座標を再計算したと言って始めましょう。しかし、私はそれらを自分の状況に適用できないようです。
ズームとスクロールができるカスタム ImageView クラスがあります。私が抱えている問題は、次のことをこの順序で行うことに起因しています。
- ポイントにズームインし、そのポイントを焦点として使用する(これは機能します)
- ズームインしたままスクロールする
- 別のポイントで拡大/縮小しようとしています (うまくいきません)
カスタム ビューの例を次に示します。赤と緑の 2 つの円があります。赤は焦点があるべき場所で、緑は焦点が実際の場所に近い場所です。
オレンジ色の円で囲まれた領域を拡大しようとすると、問題が発生します。下の写真では、オレンジ色の丸で囲まれた領域を拡大しようとしました (焦点がどこにあると計算されるかを示すためだけに、それほどではありません)。以下に示すように、赤い円は新しい焦点を正しく計算しますが、何らかの理由で緑の円は実際にズームイン/ズームアウトしている場所です。
次のコードを使用して、ズームされた座標を実際のイメージビュー座標にマップしています
public boolean onScale(ScaleGestureDetector detector) {
//update the current scale
scaleFactor *= detector.getScaleFactor();
scaleFactor = Math.max(ZOOM_LEVEL_4, Math.min(scaleFactor, ZOOM_LEVEL_0));
//applying the scaleFactor to the focal point as determined in onScaleBegin
transformMatrix.setScale(scaleFactor, scaleFactor,
newFocalPoints[0], newFocalPoints[1]);
//apply the matrix to the child
child.transform(transformMatrix, newFocalPoints[0], newFocalPoints[1],
oldFocalPoints[0], oldFocalPoints[1]);
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector){
//when a new scaling process begins, get the current imageMatrix and
//map the points to account for the current zoom level
//the initial points. based on screen location and current scroll pos
float startX = detector.getFocusX() + getScrollX();
float startY = detector.getFocusY() + getScrollY();
oldFocalPoints = new float[]{startX, startY};
//map oldFocalPoints to coordinates of the imageView based on current zoom
Matrix inverseTransformMatrix = new Matrix();
if(transformMatrix.invert(inverseTransformMatrix))
inverseTransformMatrix.mapPoints(newFocalPoints, oldFocalPoints);
return true;
}
上の写真の緑色の点は{oldCoordinates[0], oldCoordinates[1]}
デバッグ用に設定されており、正確には焦点ではありませんが、かなり近い位置にあります。そのため、新しい焦点を正しく計算しているように見えますが (赤い円)、正しく適用されていないようです。誰でも何か間違ったことを見つけることができますか? 前もって感謝します!