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 :
-
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.
-
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)
-
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) :