2010-04-29 8 views
3

Appeler setFocus(null) sur le ItemizedOverlay ne pas "unfocus" marqueur en cours. Selon la documentation:Android mapView ItemizedOverlay setFocus ne fonctionne pas correctement

... Si l'article n'est pas trouvé, ceci est un no-op. Vous pouvez également passer null pour supprimer le focus.

Voici mon code:

MapItemizedOverlay

public class MapItemizedOverlay extends ItemizedOverlay<OverlayItem> { 
    private ArrayList<OverlayItem> items = new ArrayList<OverlayItem>(); 

    public MapItemizedOverlay(Drawable defaultMarker) { 
     super(defaultMarker); 
    } 

    public void addOverlay(OverlayItem overlay) { 
     items.add(overlay); 
     populate(); 
    } 

    @Override 
    protected OverlayItem createItem(int i) { 
     return items.get(i); 
    } 

    @Override 
    public int size() { 
     return items.size(); 
    } 

} 

Création superposition de la carte et un marqueur:

StateListDrawable youIcon = (StateListDrawable)getResources().getDrawable(R.drawable.marker_icon); 
int width = youIcon.getIntrinsicWidth(); 
int height = youIcon.getIntrinsicHeight(); 
youIcon.setBounds(-13, 0-height, -13+width, 0); 
GeoPoint location = new GeoPoint(40800816,-74122009); 

MapItemizedOverlay overlay = new MapItemizedOverlay(youIcon); 
OverlayItem item = new OverlayItem(location, "title", "snippet"); 
overlay.addOverlay(item); 
mapView.getOverlays().add(overlay); 

Le R.drawable.marker_icon est défini comme suit:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_focused="true" android:drawable="@drawable/marker_selected" /> 
    <item android:state_selected="true" android:drawable="@drawable/marker_selected" /> 
    <item android:drawable="@drawable/marker_normal" /> 
</selector> 

Maintenant, pour tester le comportement setFocus() Je mets le bouton dans la fenêtre d'activité, avec l'auditeur onClick suivant:

Button focusBtn = (Button)findViewById(R.id.focusbtn); 
focusBtn.setOnClickListener(new OnClickListener() {    
    @Override 
    public void onClick(View v) { 
     for(Overlay ov : mapView.getOverlays()) 
     { 
      if(ov.getClass().getSimpleName().equals("MapItemizedOverlay") == true) 
      { 
       MapItemizedOverlay miv = (MapItemizedOverlay)ov; 
       if(miv.getFocus() == null) 
        miv.setFocus(miv.getItem(0)); 
       else 
        miv.setFocus(null); 
       break; 
      } 
     } 
     mapView.invalidate(); 
    } 
}); 

Le comportement attendu est: en cliquant sur le bouton permet de basculer la sélection du marqueur.

Cela ne fonctionne qu'une seule fois - cliquer pour la première fois sélectionne le marqueur, en cliquant à nouveau ne désélectionne pas le marqueur. La chose la plus étrange à ce sujet est qu'après avoir appelé setFocus (null), getFocus() renvoie aussi null - comme la superposition n'a pas d'élément ciblé (je l'ai débogué). Mais même après avoir appelé mapView.invalidate(), le marqueur est toujours tracé dans l'état 'selected' (focus).

Répondre

5

Comme Rpond dit dans un commentaire à ma question, il ressemble à un bug ouvert dans l'API.

En attendant, je l'ai résolu moi-même. Voici le code de contournement. Vous devez étendre la classe OverlayItem et vérifier ce que renvoie overlay.getFocus().

public class MapOverlayItem extends OverlayItem { 

    MapItemizedOverlay overlay = null; 

    public MapOverlayItem(GeoPoint point, MapItemizedOverlay ov) 
    { 
     super(point, null, null); 
     this.overlay = ov; 
    } 

    public MapOverlayItem(GeoPoint point, String title, String snippet) { 
     super(point, title, snippet); 
    } 

    @Override 
    public Drawable getMarker(int stateBitset) { 
     Drawable icon = overlay.getDefaultMarker(); 

     if(stateBitset == 0) 
      return icon; 

     OverlayItem focusedItem = overlay.getFocus(); 

     if(focusedItem == null) { 
      OverlayItem.setState(icon, 0); 
      return icon; 
     } 

     if(focusedItem.equals(this) == true) 
      OverlayItem.setState(icon, stateBitset); 
     else 
      OverlayItem.setState(icon, 0); 

     return icon;   
    } 
} 
3
+0

Peut-être. J'ai une idée de solution de contournement, mais je dois d'abord le tester. – grzaks

+0

Il semble que lorsque OverlayItem obtient le focus pour la 1ère fois, MapView recherche le StateListDrawable "state_focused". Si vous le resélectionnez à nouveau, MapView recherche "state_selected"! – Yann

+0

cette api pue, elle est terriblement conçue et a beaucoup de bugs! –

Questions connexes