Matrix
この動作を、 aView
のキャンバスの元がビューの位置によって既に変換されているということに絞り込みました。Matrix
ただし、使用してCanvas.getMatrix()
、またはを取得した場合、これは明らかではありませんView.getMatrix()
。これらの呼び出しから恒等行列を取得します。
表示されているキャンバスのオフセットView
は、画面の上部 (ステータス バー、タイトル バーなど) からの のオフセットとまったく同じ高さである可能性が最も高いです。
このユースケース、およびほとんどのユースケースでcanvas.concat(matrix)
代わりに使用することは正しいです。canvas.setMatrix(matrix)
元のマトリックスが本当に必要な場合は、デバッグ時に行ったので、 をView
独自に翻訳して手動で変換する必要がありWindow
ます。
int[] viewLocation = new int[2];
mView.getLocationInWindow(viewLocation);
mOriginalMatrix.setTranslate(viewLocation[0], viewLocation[1]);
コメントで追加の質問に答えるために編集します。
タッチ座標 (または任意の画面座標) を a の座標に一致するように変換するには、代わりにCanvas
すべての変換を に行い、そのマトリックスを使用して各フレームを描画します。(または、現在行っているようにすべての変換を直接実行し続け、各描画後にマトリックスを取得するために使用することもできます。非推奨ですが、機能します。)Matrix
Canvas.concat()
Canvas
Canvas.getMatrix(mMyMatrix)
次に、マトリックスを使用して、元のグリッド境界を画面に描画されたものに変換できます。基本的に、グリッドを描画するときとまったく同じことをCanvas
行っており、グリッドのコーナー ポイントを画面座標に変換しています。グリッドは、タッチ イベントと同じ座標系になります。
private final Matrix mMyMatrix = new Matrix();
// Assumes that the grid covers the whole View.
private final float[] mOriginalGridCorners = new float[] {
0, 0, // top left (x, y)
getWidth(), getHeight() // bottom right (x, y)
};
private final float[] mTransformedGridCorners = new float[4];
@Override
public boolean onTouchEvent(MotionEvent event) {
if (/* User pans the screen */) {
mMyMatrix.postTranslate(deltaX, deltaY);
}
if (/* User zooms the screen */) {
mMyMatrix.postScale(deltaScale, deltaScale);
}
if (/* User taps the grid */) {
// Transform the original grid corners to where they
// are on the screen (panned and zoomed).
mMyMatrix.mapPoints(mTransformedGridCorners, mOriginalGridCorners);
float gridWidth = mTransformedGridCorners[2] - mTransformedGridCorners[0];
float gridHeight = mTransformedGridCorners[3] - mTransformedGridCorners[1];
// Get the x and y coordinate of the tap inside the
// grid, between 0 and 1.
float x = (event.getX() - mTransformedGridCorners[0]) / gridWidth;
float y = (event.getY() - mTransformedGridCorners[1]) / gridHeight;
// To get the tapped grid cell.
int column = (int)(x * nbrColumns);
int row = (int)(y * nbrRows);
// Or to get the tapped exact pixel in the original grid.
int pixelX = (int)(x * getWidth());
int pixelY = (int)(y * getHeight());
}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
// Each frame, transform your canvas with the matrix.
canvas.save();
canvas.concat(mMyMatrix);
// Draw grid.
grid.draw(canvas);
canvas.restore();
}
または、マトリックスを取得するための非推奨の方法です。これはまだ機能しており、おそらく変更が少なくて済みます。
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
// Transform canvas and draw the grid.
grid.draw(canvas);
// Get the matrix from canvas. Can be used to transform
// corners on the next touch event.
canvas.getMatrix(mMyMatrix);
canvas.restore();
}