27 votes

Android imageView: définition des paramètres de zoom par glisser et pincer

Je suis actuellement en train de développer pour Android (ma première application) une application qui permet aux utilisateurs de voir le plan du métro et de pouvoir zoomer et faire glisser.

Je suis en train de modifier le code trouvé dans Hello Android, 3ème édition et j'ai réussi à faire fonctionner le zoom et le glisser. J'utilise Matrix comme échelle de mise en page.

Cependant, j'ai maintenant 3 problèmes :

  1. J'ai essayé beaucoup de choses pour limiter les paramètres du glisser mais je n'arrive pas à empêcher l'élément d'être glissé hors de la vue parente (et peut en fait disparaître de la vue). J'ai essayé de définir les paramètres de mise en page dans le fichier XML et cela ne fonctionne tout simplement pas.

  2. Je peux zoomer avec pincement mais j'ai du mal, encore une fois, à limiter la quantité de zoom. J'essaie de jouer avec le paramètre max_zoom et min_zoom pour limiter la valeur d'échelle (je posterai mon code après)

  3. J'ai aussi du mal à mapp une coordonnée sur mon image afin que les gens puissent cliquer sur certaines parties (tout l'intérêt de cela est de permettre aux utilisateurs de cliquer sur une station sur la carte et de consulter des informations à ce sujet)

J'ai l'impression d'avoir des problèmes parce que j'utilise l'échelle de matrice.

Voici mon code actuel :

Touch.java

package org.example.touch;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.GridView;
import android.widget.ImageView;

public class Touch extends Activity implements OnTouchListener {
private static final String TAG = "Touch";

private static final float MIN_ZOOM = 1.0f;
private static final float MAX_ZOOM = 5.0f;

// Ces matrices seront utilisées pour déplacer et zoomer l'image
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();

// Nous pouvons être dans l'un de ces 3 états
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;

// Se rappeler de certaines choses pour le zoom
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;

@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.main);
   ImageView view = (ImageView) findViewById(R.id.imageView);
   //view.setLayoutParams(new GridView.LayoutParams(85, 85));
   view.setScaleType(ImageView.ScaleType.FIT_CENTER);
   view.setOnTouchListener(this);   
}

public boolean onTouch(View v, MotionEvent event) {
   ImageView view = (ImageView) v;
   view.setScaleType(ImageView.ScaleType.MATRIX);
   float scale;

   // Enregistrer l'événement tactile dans le log
   dumpEvent(event);

   // Gérer les événements tactiles ici...
   switch (event.getAction() & MotionEvent.ACTION_MASK) {

   case MotionEvent.ACTION_DOWN: //premier doigt en bas seulement
      savedMatrix.set(matrix);
      start.set(event.getX(), event.getY());
      Log.d(TAG, "mode=DRAG" );
      mode = DRAG;
      break;
   case MotionEvent.ACTION_UP: //premier doigt levé
   case MotionEvent.ACTION_POINTER_UP: //deuxième doigt levé
      mode = NONE;
      Log.d(TAG, "mode=NONE" );
      break;
   case MotionEvent.ACTION_POINTER_DOWN: //deuxième doigt en bas
      oldDist = spacing(event);
      Log.d(TAG, "oldDist=" + oldDist);
      if (oldDist > 5f) {
         savedMatrix.set(matrix);
         midPoint(mid, event);
         mode = ZOOM;
         Log.d(TAG, "mode=ZOOM" );
      }
      break;

   case MotionEvent.ACTION_MOVE: 
      if (mode == DRAG) { //mouvement du premier doigt
         matrix.set(savedMatrix);
         if (view.getLeft() >= -392){
            matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
         }
      }
      else if (mode == ZOOM) { //zoom à pincement
         float newDist = spacing(event);
         Log.d(TAG, "newDist=" + newDist);
         if (newDist > 5f) {
            matrix.set(savedMatrix);
            scale = newDist / oldDist; **//penser que je dois jouer avec cette valeur pour la limiter**
            matrix.postScale(scale, scale, mid.x, mid.y);
         }
      }
      break;
   }

   // Effectuer la transformation
   view.setImageMatrix(matrix);

   return true; // indiquer que l'événement a été géré
}

private float spacing(MotionEvent event) {
   float x = event.getX(0) - event.getX(1);
   float y = event.getY(0) - event.getY(1);
   return FloatMath.sqrt(x * x + y * y);
}

private void midPoint(PointF point, MotionEvent event) {
   float x = event.getX(0) + event.getX(1);
   float y = event.getY(0) + event.getY(1);
   point.set(x / 2, y / 2);
}

/** Montrer un événement dans la vue LogCat, pour le débogage */
private void dumpEvent(MotionEvent event) {
   String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" ,
      "POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" };
   StringBuilder sb = new StringBuilder();
   int action = event.getAction();
   int actionCode = action & MotionEvent.ACTION_MASK;
   sb.append("event ACTION_" ).append(names[actionCode]);
   if (actionCode == MotionEvent.ACTION_POINTER_DOWN
         || actionCode == MotionEvent.ACTION_POINTER_UP) {
      sb.append("(pid " ).append(
      action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
      sb.append(")" );
   }
   sb.append("[" );
   for (int i = 0; i < event.getPointerCount(); i++) {
      sb.append("#" ).append(i);
      sb.append("(pid " ).append(event.getPointerId(i));
      sb.append(")=" ).append((int) event.getX(i));
      sb.append("," ).append((int) event.getY(i));
      if (i + 1 < event.getPointerCount())
         sb.append(";" );
   }
   sb.append("]" );
   Log.d(TAG, sb.toString());
}
}

main.xml (assez simple, rien de vraiment compliqué) :

AndroidManifest.xml (seul le thème a été ajouté pour qu'il n'y ait pas de barre de titre et qu'il soit en plein écran) :

5voto

Jana Points 1582

Utilisez le code dans le commentaire de Phyxdevel dans le lien ci-dessous Exemple de zoom ZDNET.

Il a le code pour restreindre le panoramique et le niveau de zoom.

0voto

Ankit Points 862

Vous pouvez utiliser le code suivant pour limiter le bas et la droite

float maxX = minX+viewWidth; 
int offsetY = 80;
        float maxY = minY+viewHeight-offsetY;
       if(x>maxX){
           mPosX = maxX;
       }
       if(xmaxY){
           mPosY = maxY;
       }
       if(y

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X