Sono stato bloccato su questo problema per otto ore, quindi ho pensato che fosse giunto il momento di ottenere aiuto.Canvas Pinch-Zoom to Point Within Bounds
Prima di iniziare il mio problema, farò sapere che ho visitato questo sito e Google, e nessuna delle risposte che ho trovato ha aiutato. (This è uno, another e another.)
Ecco il punto: ho una classe che estende SurfaceView
(chiamiamolo MySurface
) e le sostituzioni molti metodi in esso. Normalmente, disegna diversi quadrati e caselle di testo, il che va bene. Non appena un utente inizia a toccare, converte in uno Bitmap
, quindi disegna ogni fotogramma fino a quando l'utente non rilascia.
Ecco il problema: voglio implementare una funzionalità di questo tipo che l'utente può posizionare due dita sullo schermo, pizzicare per ingrandire, e anche scorrere intorno (ma SOLO con due dita verso il basso).
ho trovato un paio di implementazioni di pinch-to-zoom e adattato alla mia Canvas
oggetto MySurface
tramite il seguente:
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.scale(mScaleVector.z, mScaleVector.z); // This is the scale factor as seen below
canvas.translate(mScaleVector.x, mScaleVector.y); // These are offset values from 0,0, both working fine
// Start draw code
// ...
// End draw code
canvas.restore();
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
float factor = detector.getScaleFactor();
if (Math.abs(factor - 1.0f) >= 0.0075f) {
mScaleVector.z *= factor;
mScaleVector.z = Math.max(MIN_ZOOM, Math.min(mScaleVector.z, MAX_ZOOM));
}
// ...
invalidate();
return true;
}
}
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction() & MotionEvent.ACTION_MASK;
int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
if (event.getPointerCount() == 2) {
if (action == MotionEvent.ACTION_POINTER_DOWN && pointerIndex == 1) {
// The various pivot coordinate codes would belong here
}
}
detector.onTouchEvent(event); // Calls the Scale Gesture Detector
return true;
}
Mentre entrambi gli elementi funzionano bene - lo scorrimento avanti e indietro e il pizzico -to-zoom: c'è un grosso problema. Il pinch-to-zoom, se utilizzato, ingrandisce il punto 0,0
, anziché lo zoom nel punto dito.
Ho provato un sacco di modi per risolvere questo:
- Utilizzando
canvas.scale(mScaleVector.z, mScaleVector.z, mScaleVector.x, mScaleVector.y);
; ovviamente, questo produce risultati indesiderati poiché i valori di xxe sono 0-offset. - Gestione di una coordinata "pivot" che utilizza lo stesso offset del metodo
translate()
, ma questo produce lo stesso problema0,0
o il salto quando la vista viene toccata. - Numerose altre cose ... Ho fatto molto con la coordinata del perno di cui sopra, cercando di basare la sua posizione sul primo tocco dell'utente e spostandolo rispetto a quel tocco ogni gesto successivo.
Inoltre, questa tela deve essere limitata, quindi l'utente non può scorrere per sempre. Tuttavia, quando utilizzo il metodo .scale(sx, sy, px, py)
, spinge le cose oltre i limiti impostati in .translate()
.
Sono ... praticamente aperto a tutto a questo punto. So che questa funzionalità può essere aggiunta, come si vede nella galleria di Android 4.0 (durante la visualizzazione di una singola immagine). Ho provato a rintracciare il codice sorgente che gestisce questo, senza alcun risultato.
Gestisco personalmente le posizioni delle due dita direttamente con 'onTouchEvent'. Con questo, è possibile trovare facilmente il punto medio e la quantità di ridimensionamento richiesta. – Doomsknight
puoi postare la soluzione se hai risolto il problema che sto affrontando lo stesso problema, e il mio cliente è .... :(, o puoi dirmi come hai risolto il problema grazie – AkashG