我對編碼相當陌生,並且是全新的圖形。我會感激一些方向,因爲我一直無法找到我需要的答案。Android - 如何在縮放後找到矩形
我有一個擴展視圖的類。我在自定義畫布中創建了幾個3層結構的矩形。我成功地能夠觸摸並移動每個矩形。我可以平移整個畫布。在我平移之後,我可以移動單個矩形。我可以放大整個屏幕。我不能做的一件事是在縮放之後移動單個矩形。縮放後我無法「找到」反光板。我準備放棄整個自定義視圖,並嘗試使用imageview或者我可以處理的事情來嘗試查看座標所觸及的內容。
我的問題是:你怎麼在縮放後找到矩形的座標?我的猜測是基於畫布的移動或畫布的比例來重新計算每一個矩形,但顯然我錯過了一些東西,因爲這看起來過於複雜,並且不適合我。
下面是一些代碼 - 請原諒這個爛攤子,我只是想讓這個想法失敗。我嘗試過使用矩陣以及計算器中的比例因子,但都沒有讓我處於正確的位置。 (某些代碼不使用 - 我用它,但不能得到它來計算,其中rects是正確的......如果可以的,甚至這樣做的正確方法?)
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(xOffset, yOffset);
canvas.scale(scaleFactor, scaleFactor);
for (RectF r: RectFs){
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLACK);
canvas.drawRoundRect(r, 20, 20,paint); //Set a border
paintShader.setStyle(Style.FILL);
paintShader.setShader(new LinearGradient(r.left, r.bottom, r.right, r.top, Color.CYAN, Color.YELLOW, Shader.TileMode.REPEAT));
canvas.drawRoundRect(r, 20, 20, paintShader);
paint.setColor(Color.BLACK);
paint.setTextSize(textSize);
paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
paint.setLinearText(true);
canvas.drawText(text, r.left+px, r.top+py, paint);
}
}
public boolean onTouchEvent(MotionEvent event) {
scaleGestureDetector.onTouchEvent(event);
touched = true;
if (!panned){
left = event.getX() - rectHeight/2;
top = event.getY() - rectWidth/2;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startPos.set(event.getX(), event.getY());
findWhatWasTouched();
invalidate();
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_MOVE:
if (freezeAction)
break;
// Only move if the ScaleGestureDetector isn't processing a gesture.
if (!scaleGestureDetector.isInProgress() && panned) {
xOffset += event.getX() - startPos.x;
yOffset += event.getY() - startPos.y;
} else
resetAllRectsAfterScrollOrZoom();
findWhatWasTouched();
invalidate();
startPos.set(event.getX(), event.getY());
break;
case MotionEvent.ACTION_POINTER_UP:
freezeAction = true;// When two fingers off of zoom, don't let the other finger jump everything around
break;
case MotionEvent.ACTION_UP:
if (!freezeAction){
findWhatWasTouched();
invalidate();
if (panned || zoomed)
resetAllRectsAfterScrollOrZoom();
}
liveRect = null;
panned = false;
freezeAction = false;
xOffset = 0;
yOffset =0;
break;
}
return true;
}
public void resetAllRectsAfterScrollOrZoom(){
float height, width;
for (RectF r: RectFs){
height = r.height();
width = r.width();
if (zoomed){
r.left += (xOffset * scaleFactor);
r.top += (yOffset * scaleFactor);
}else {
r.left += xOffset;
r.top += yOffset ;
}
r.right = r.left + width;
r.bottom = r.top + height;
}
}
public void findWhatWasTouched(){
boolean rectWasTouched = false;
for (RectF r: RectFs){ // Update positions due to a touch event.
if (r.contains(startPos.x, startPos.y)){
if (liveRect == null)
liveRect = r;
rectWasTouched = true;
}
}
if (!rectWasTouched)
panned = true;
if (!zoomed && !panned && liveRect != null){
float height = liveRect.height();
float width = liveRect.width();
liveRect.left = left;
liveRect.top = top;
liveRect.right = liveRect.left + width;
liveRect.bottom = liveRect.top + height; // We have a moving single rect - reset it's position here
}
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
scaleFactor *= detector.getScaleFactor();
zoomed = true;
// don't let the object get too small or too large.
scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 5.0f));
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector){
zoomed = false;
}
} // End ScaleListener class
} // End view class
最大的問題是因爲在縮放之後觸摸了rects,當我朝那個方向移動時,將revers進一步向下移動&,呈指數形式......這導致我認爲resetAllRects塊的縮放部分中的數學錯誤。但對於我的生活,我無法弄清楚。仍然不知道是否每次重置矩形座標是否是正確的方法?