La mise en œuvre pincée de zoom et faites glisser à l'aide Android de construire dans le geste de l'auditeur et de l'échelle de l'écouteur
Je suis en train de mettre en œuvre pincée de zoom et faites glisser à l'aide Android le geste de l'auditeur et de l'échelle de l'auditeur. Le problème est que quand j'exécute pincée de zoom, l'image (que je suis en train de zoom) rebondit à un emplacement particulier. Aussi la position du zoom n'est pas centré.
Le code suivant montre ce que je suis en train de réaliser. Aucune idée de pourquoi l'image est de sauter (et comment le corriger) ?
public class CustomView extends View {
Bitmap image;
int screenHeight;
int screenWidth;
Paint paint;
GestureDetector gestures;
ScaleGestureDetector scaleGesture;
float scale = 1.0f;
float horizontalOffset, verticalOffset;
int NORMAL = 0;
int ZOOM = 1;
int DRAG = 2;
boolean isScaling = false;
float touchX, touchY;
int mode = NORMAL;
public CustomView(Context context) {
super(context);
//initializing variables
image = BitmapFactory.decodeResource(getResources(),
R.drawable.image_name);
//This is a full screen view
screenWidth = getResources().getDisplayMetrics().widthPixels;
screenHeight = getResources().getDisplayMetrics().heightPixels;
paint = new Paint();
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
paint.setColor(Color.WHITE);
scaleGesture = new ScaleGestureDetector(getContext(),
new ScaleListener());
gestures = new GestureDetector(getContext(), new GestureListener());
mode = NORMAL;
initialize();
}
//Best fit image display on canvas
private void initialize() {
float imgPartRatio = image.getWidth() / (float) image.getHeight();
float screenRatio = (float) screenWidth / (float) screenHeight;
if (screenRatio > imgPartRatio) {
scale = ((float) screenHeight) / (float) (image.getHeight()); //fit height
horizontalOffset = ((float) screenWidth - scale
* (float) (image.getWidth())) / 2.0f;
verticalOffset = 0;
} else {
scale = ((float) screenWidth) / (float) (image.getWidth()); //fit width
horizontalOffset = 0;
verticalOffset = ((float) screenHeight - scale
* (float) (image.getHeight())) / 2.0f;
}
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.drawColor(0, Mode.CLEAR);
canvas.drawColor(Color.WHITE);
if(mode == DRAG || mode == NORMAL) {
//This works perfectly as expected
canvas.translate(horizontalOffset, verticalOffset);
canvas.scale(scale, scale);
canvas.drawBitmap(image, getMatrix(), paint);
}
else if (mode == ZOOM) {
//PROBLEM AREA - when applying pinch zoom,
//the image jumps to a position abruptly
canvas.scale(scale, scale, touchX, touchY);
canvas.drawBitmap(image, getMatrix(), paint);
}
canvas.restore();
}
public class ScaleListener implements OnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scaleFactorNew = detector.getScaleFactor();
if (detector.isInProgress()) {
touchX = detector.getFocusX();
touchY = detector.getFocusY();
scale *= scaleFactorNew;
invalidate(0, 0, screenWidth, screenHeight);
}
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
isScaling = true;
mode=ZOOM;
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
mode = NORMAL;
isScaling = false;
}
}
public class GestureListener implements GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener {
@Override
public boolean onDown(MotionEvent e) {
isScaling = false;
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
if (!isScaling) {
mode = DRAG;
isScaling = false;
horizontalOffset -= distanceX;
verticalOffset -= distanceY;
invalidate(0, 0, screenWidth, screenHeight);
} else {
mode = ZOOM;
isScaling = true;
}
return true;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
scaleGesture.onTouchEvent(event);
gestures.onTouchEvent(event);
return true;
}
}
Merci d'avance.
- si vous n'utilisez pas le mode de glissement avant d'utiliser le mode ZOOM - sens, le ZOOM est la 1ère chose que vous faites avant toute traduction est appliquée, cette image est encore sauter?
- Oui l'image est encore sauts.
- ne pas le horizontal / vertical offset être appliquée même lorsque vous êtes à la mise à l'échelle? avez-vous essayé l'application de ces la mise à l'échelle?
- L'échelle horizontale et verticale doivent être appliquées lors de la mise à l'échelle ainsi. Mais cela ne fait aucune différence - l'image est encore sauts. Il semble que j'ai besoin de jouer avec la mise à l'échelle de points de pivot. Une question similaire (mais avec une beaucoup plus propre mise en œuvre) est également posée ici: stackoverflow.com/questions/19471356/... Comme pour la réponse à cette question, les pivots autour desquels nous sommes de mise à l'échelle doit être ajustée. Je suis encore à me gratter la tête, en vain, de calculer le pivot coordonnées.
- comment essayer de définir la touchX / délicat dans votre onScaleBegin? Est ce que cela change quelque chose?
- Na pas aider 🙁
Vous devez vous connecter pour publier un commentaire.
J'ai mis en œuvre ce comportement, et j'ai utilisé une matrice à traiter toutes les opérations de zoom et de défilement (et de la rotation, dans mon cas). Il en fait soigné code et fonctionne comme sur des roulettes.
Stocker une Matrice comme un membre de la classe:
Edit: Magasin de la vieille mise au point, utilisé pour obtenir le décalage de mise au point pendant la mise à l'échelle.
Modifier: Ensemble lastFocus variables dans onScaleBegin
Remplacer votre onScale:
De même dans onScroll:
dans onDraw; Dessinez avec votre drawMatrix:
Bon codage!
transformationMatrix.postTranslate(focusX + focusShiftX), focusY + focusShiftY);
àtransformationMatrix.postTranslate(focusX, focusY);