Comment puis-je modifier TouchImageView avec double tap pour zoomer?
Je suis la modification de la TouchImageView (https://github.com/MikeOrtiz/TouchImageView/issues) pour avoir zoom avant et zoom arrière lorsque vous appuyez deux fois sur. J'ai commencé par ce post - Comment TouchImageView œuvres? et nous avons ajouté la détection de mouvement.
Maintenant, je dois mettre en œuvre le zoom avant et zoom arrière dont je ne suis pas sûr de la façon de faire. Voici le code que j'ai jusqu'à présent avec la zoomIn et zoomOut méthodes non implémentées. Quelqu'un sait comment faire cela? En outre, j'ai remarqué que le zoom par pincement n'a pas vraiment de zoom à l'emplacement où vous pincer, alors j'espérais que cela pourrait être fait pour se comporter plus comme la gallery3D pincée de zoom. Merci.
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
import android.view.View;
import android.widget.ImageView;
public class TouchImageView extends ImageView {
private static final String TAG = TouchImageView.class.getSimpleName();
Matrix matrix = new Matrix();
//We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
//Remember some things for zooming
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 3f;
float[] m;
float redundantXSpace, redundantYSpace;
float width, height;
static final int CLICK = 3;
float saveScale = 1f;
float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
ScaleGestureDetector mScaleDetector;
private GestureDetector gestureDetector;
Context context;
public TouchImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public TouchImageView(Context context) {
super(context);
init(context);
}
public void init(Context context) {
gestureDetector = new GestureDetector(new DoubleTapGestureListener());
super.setClickable(true);
this.context = context;
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
matrix.setTranslate(1f, 1f);
m = new float[9];
setImageMatrix(matrix);
setScaleType(ScaleType.MATRIX);
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
mScaleDetector.onTouchEvent(event);
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
PointF curr = new PointF(event.getX(), event.getY());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
last.set(event.getX(), event.getY());
start.set(last);
mode = DRAG;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
float scaleWidth = Math.round(origWidth * saveScale);
float scaleHeight = Math.round(origHeight * saveScale);
if (scaleWidth < width) {
deltaX = 0;
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
} else if (scaleHeight < height) {
deltaY = 0;
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
} else {
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
}
matrix.postTranslate(deltaX, deltaY);
last.set(curr.x, curr.y);
}
break;
case MotionEvent.ACTION_UP:
mode = NONE;
int xDiff = (int) Math.abs(curr.x - start.x);
int yDiff = (int) Math.abs(curr.y - start.y);
if (xDiff < CLICK && yDiff < CLICK)
performClick();
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
}
setImageMatrix(matrix);
invalidate();
return true; //indicate event was handled
}
});
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
bmWidth = bm.getWidth();
bmHeight = bm.getHeight();
}
public void setMaxZoom(float x) {
maxScale = x;
}
private class ScaleListener extends SimpleOnScaleGestureListener {
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
mode = ZOOM;
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
LogUtil.i(TAG, detector.getScaleFactor() + " " + detector.getFocusX() + " " + detector.getFocusY());
float mScaleFactor = (float) Math.min(Math.max(.95f, detector.getScaleFactor()), 1.05);
float origScale = saveScale;
saveScale *= mScaleFactor;
if (saveScale > maxScale) {
saveScale = maxScale;
mScaleFactor = maxScale / origScale;
} else if (saveScale < minScale) {
saveScale = minScale;
mScaleFactor = minScale / origScale;
}
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
if (origWidth * saveScale <= width || origHeight * saveScale <= height) {
matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2);
if (mScaleFactor < 1) {
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1) {
if (Math.round(origWidth * saveScale) < width) {
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
} else {
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
}
}
}
} else {
matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1) {
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
}
}
return true;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
//Fit to screen.
float scale;
float scaleX = (float) width / (float) bmWidth;
float scaleY = (float) height / (float) bmHeight;
scale = Math.min(scaleX, scaleY);
matrix.setScale(scale, scale);
setImageMatrix(matrix);
saveScale = 1f;
//Center the image
redundantYSpace = (float) height - (scale * (float) bmHeight);
redundantXSpace = (float) width - (scale * (float) bmWidth);
redundantYSpace /= (float) 2;
redundantXSpace /= (float) 2;
matrix.postTranslate(redundantXSpace, redundantYSpace);
origWidth = width - 2 * redundantXSpace;
origHeight = height - 2 * redundantYSpace;
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
setImageMatrix(matrix);
}
class DoubleTapGestureListener extends SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
//event when double tap occurs
@Override
public boolean onDoubleTap(MotionEvent e) {
float x = e.getX();
float y = e.getY();
LogUtil.i(TAG, "Tapped at: (" + x + "," + y + ")");
if (isZoomed()) {
zoomOut();
} else {
zoomIn();
}
return true;
}
}
public boolean isZoomed() {
return saveScale > minScale; //this seems to work
}
public void zoomIn() {
LogUtil.i(TAG, "Zooming in");
//TODO: no idea how to do this
}
public void zoomOut() {
LogUtil.i(TAG, "Zooming out");
//TODO: no idea how to do this
}
}
- vérifier cette fourche de TouchImageView avec tap-to-zoom, de la mise en œuvre
Vous devez vous connecter pour publier un commentaire.
Ma réponse peut-être pas exactement spécifiques à votre problème, mais il couvre ImageView Zooom in/out, appuyez deux fois sur, la Délimitation de l'image dans Imageview lors de son zoom , En bref, est exactement comme la Galerie par défaut de l'app de Android
http://blog.sephiroth.it/2011/04/04/imageview-zoom-and-scroll/
Que le blog dit:
Double le courant de zoom pour effectuer un zoom avant, puis retourne à l'origine de niveau de zoom:
Vouloir traduire la matrice de centre sur le point de l'utilisateur double-clique.
@sherlock,
Si vous voulez effectuer un zoom arrière lorsque le double-touchez-le à nouveau, vous pouvez écrire une méthode comme ci-dessous:
Remarque: Dans le cas où un téléphone est Mou de Barre de Navigation (comme le Nexus 5), vous devez recalculer la distance à traduire. Dans mon exemple, navBarHeight est la variable qui sera définie par la fonction:
Laissez-moi savoir si cela aide.
En Double-tapant et d'autres gestes peuvent être détectés comme suit:
Fling détection de mouvement sur la grille de mise en page
J'espère que cela aide...
Emmanuel
Avec la classe TouchImageView ci-dessus, si vous souhaitez appliquer Double Tap, vous pouvez faire quelques étapes:
Déclarer la variable:
Initialisation dans le constructeur:
Inscrire dans onTouch():
Écrire la méthode handleScale() - coppied de onScale() méthode - comme ci-dessous:
Mettre dans zoomIn() méthode:
Dans la substitution de la méthode onScale(), vous pouvez modifier comme:
à suivre SÈCHE principe.
Remarque: appuyez deux fois sur a pour seul effet avec la petite touche de la zone.
Laissez-moi savoir si cela fonctionne pour vous.