Aller au contenu

[Résolu] Création d'un système type "Google Maps"


Thiphariel

Recommended Posts

Bonjour !

Je dois réaliser une application proche du système Google Maps, mais en utilisant des fonds de carte personnalisés (crées par ma boite, ces derniers au format SVG)

Afin de garder les interactions Javascript du SVG, je dois donc passer par des WebView (Stoppez moi si je me trompe ! ^^)

Mon problème est le suivant :

Comment gérer facilement plusieurs niveaux de zoom dans une WebView ? Pour cela, j'ai testé de faire un appel a "loadUrl()" une fois un certain niveau de zoom atteint et calculer le scroll effectué sur la vue actuelle afin de replacer la nouvelle comme il le faut, mais sans succès ... Le nouveau SVG chargé se mets en (0, 0) avant de se déplacer au mauvais endroit (problème de calcul mais ce n'est pas tellement le sujet du problème)

@Override
public boolean onTouchEvent(MotionEvent event) {
 if(event.getAction() == MotionEvent.ACTION_UP) {
	 //Log.i("Scale", Float.toString(getScale()));
	 // Calcul des scrolls ...

	 if(getScale() > 4.0) {
		 loadUrl("file:///android_asset/zoom4.svg");
	 }
 }

 return super.onTouchEvent(event);
}

Je suis ici dans une classe perso héritant de WebView, afin de redéfinir les TouchEvents.

Si quelqu'un aurait une idée de comment bien procéder pour faire cela, je suis preneur d'avis !

Merci à tous

PS : Pour ce qui est du "getScale()" dans le code, je sais qu'il est deprecated, seulement, pour mes tests cela m'est plus rapide que de le calculer manuellement.

Lien vers le commentaire
Partager sur d’autres sites

Je reviens au nouvelles, avec quelque chose de plutôt fonctionnel (en phase alpha si je puis dire ...)

J'ai donc créé une classe qui étends WebView :

enum ZoomLevel {
LEVEL_1,
LEVEL_2,
LEVEL_3,
LEVEL_4
}
public class TouchWebView extends WebView {
private Point _scroll;
private float _scale;
private ZoomLevel _zoom;
//private static final float RATIO = 2.46f;
public TouchWebView(Context context, AttributeSet attrs) {
 super(context, attrs);
 // TODO Auto-generated constructor stub
 _scroll = new Point(0,0);
 _scale = 2.0f;
 _zoom = ZoomLevel.LEVEL_2;
 setWebViewClient(new WebViewClient() {
  @Override
  public void onPageStarted(WebView view, String url, Bitmap favicon) {
   view.setAlpha(0.1f);
  }
  @Override
  public void onPageFinished(final WebView view, String url) {
   Log.i("FINISHED", ":)");
   view.scrollTo(_scroll.x, _scroll.y);
   view.setAlpha(1f);
  }
 });
}
@Override
public boolean onTouchEvent(MotionEvent event) {
 _scale = getScale(); //Pas beau, à corriger plus tard

 if(getAlpha() < 1.0f) {
  return false;
 }

 switch(event.getAction()) {
 case MotionEvent.ACTION_MOVE:
  if(event.getPointerCount() > 1) {
   switch(_zoom) {
   case LEVEL_2:
 if(_scale >= 4.0) {
  doZoom(ZoomLevel.LEVEL_3, 400, "file:///android_asset/zoom3.svg");
  event.setAction(MotionEvent.ACTION_CANCEL);
 }
 break;
   case LEVEL_3:
 if(_scale < 2.5) {
  doZoom(ZoomLevel.LEVEL_2, 250, "file:///android_asset/zoom2.svg");
  event.setAction(MotionEvent.ACTION_CANCEL);
 }
 if(_scale > 6.5) {
  doZoom(ZoomLevel.LEVEL_4, 650, "file:///android_asset/zoom4.svg");
  event.setAction(MotionEvent.ACTION_CANCEL);
 }
 break;
   case LEVEL_4:
 if(_scale < 4.0) {
  doZoom(ZoomLevel.LEVEL_3, 400, "file:///android_asset/zoom3.svg");
  event.setAction(MotionEvent.ACTION_CANCEL);
 }
 break;
   }
  }
  break;
 }
 return super.onTouchEvent(event);
}
private void doZoom(ZoomLevel level, int scale, String url) {
 _scroll.x = (int) (getScrollX());
 _scroll.y = (int) (getScrollY());
 Log.i("SCROLL",_scroll.x + " / " + _scroll.y);
 _zoom = level;
 setInitialScale(scale);
 loadUrl(url);
}
}

Alors, mon souci, déjà je pense que ça peut être améliorer, mais je vais m'en occuper au fur et à mesure, ensuite, au niveau des "setAlpha()", je les ai mit car cela me permet de voir le comportement de la WebView chargée : Elle se recharge totalement au appel des "loadUrl()" (Ce qui est tout à fait normal avec ce code actuel je le comprends)

Ce qu'il me faudrait actuellement, c'est un moyen de charger les différents niveau de zoom au lancement de l'application, mais je ne sais malheureusement pas comment faire avec mon code actuel.

Quelqu'un aurait-il une idée ?

Merci !

Lien vers le commentaire
Partager sur d’autres sites

Plutôt que de charger directement un SVG dans ta WebView, peut-être pourrais-tu charger une page html, qui elle contiendrait tous les SVG, que tu pourrais ensuite activer/désactiver à volonté ?

Lien vers le commentaire
Partager sur d’autres sites

Salut.

Merci pour ta réponse déjà. Tu penses que ça serait plus simple à manipuler comme cela ?

Je pensais qu'il existait un moyen de précharger les SVG afin de juste les switcher selon le niveau de zoom..

Peut être devrais-je m'orienter vers ta technique ^^

Lien vers le commentaire
Partager sur d’autres sites

Vu que c'est la WebView qui charge le SVG, à chaque fois que tu fais un loadUrl, c'est comme si tu changais de page dans ton navigateur, le contexte de la WebView est réinitialisé. Donc, si tu veux les précharger, il faut que ce soit la WebView qui le fasse, et je vois cette solution pour y arriver

Lien vers le commentaire
Partager sur d’autres sites

Un ami m'a donné l'astuce !

Il faut charger les SVG dans le onCreate() de l'activity qui affiche la WebView (en mettant une ProgressBar histoire de montrer que ca mouline et en mettant la WebView invisible au départ puis visible une fois chargée) et ensuite les futurs appel des LoadUrl sont énormément plus rapides !

Merci en tout cas chpil de t'y être penché ! :-)

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...