Odd behavior with Android ZoomControls and Callout

1139
8
Jump to solution
05-14-2012 11:04 AM
deleted-user-ATjHIWsdQYmT
Occasional Contributor III
I have encountered some odd behavior when using the stock Android zoom controls. while a callout is visible.  Here is what I've found:
1.  show a callout.
2.  while the callout is shown, zoom in/out on the map using the zoom controls
3.  hide the callout (I do it via a button on the callout itself)
4.  zoom in/out using the zoomcontrols. 

After zooming in/out the callout reappears.  I'm not sure what is showing the callout again because while debugging my callout.show() is not being hit again.

Here is my (very simple) code for zooming in/out:
ZoomControls zoomCtl = (ZoomControls) findViewById(R.id.zoomControls1);  zoomCtl.setOnZoomInClickListener(new View.OnClickListener(){    @Override    public void onClick(View v){     mMapView.zoomin();    }   });   zoomCtl.setOnZoomOutClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {     mMapView.zoomout();    }   });  


Any ideas?
0 Kudos
1 Solution

Accepted Solutions
AndyGup
Esri Regular Contributor
How about the following:

Scenario 1 - callout always visible:

Callout is visible.
[set Esri zoom listener to null -- e.g. map.setOnZoomListener(null);]
Click Zoom Out on zoomcontrol
Call should stay visible

Scenario 2 - callout always closed:

Callout is visible.
[user closes callout]
[re-initialize a new Esri zoom listener]
Click Zoom Out on zoomcontrol
the callout disappears.

I haven't tried this but it sounds like it would work. What do you think?

-Andy

View solution in original post

0 Kudos
8 Replies
AndyGup
Esri Regular Contributor
Check the properties of the view object that's being passed by the View.OnClickListener. It's possible that listener is passing in a copy of the View which contains a different State.


public void onClick(View v){
    mMapView.zoomin();
}

versus

public void onClick(View v){
    v.zoomin();
}



-Andy
0 Kudos
deleted-user-ATjHIWsdQYmT
Occasional Contributor III
Andy,

Thanks for the suggestion.  The view object being passed is the zoombutton, not the mapview, thus there is no "v.zoomin()" method. 

Any other suggestions?

Thanks again for all your help
-Andrew
0 Kudos
AndyGup
Esri Regular Contributor
Ah, right, because we don't currently support ZoomControls directly in com.esri.android.map.MapView. You set up a stand-alone ZoomControl and that's why the listener is returning your zoomButton as the scope. Got it.

So, I was able to reproduce the behavior. While it's not exactly clear what's causing the problem,  I suspect it's related to the View.OnClickListener and we'd have to dig deeper.

As a temporary workaround, by simply setting up an OnZoomListener I was able to modify the behavior of the callout. When I implemented this pattern the callout seems to always hide() when using the ZoomControl, which isn't 100% ideal . Maybe you can work with something related to this for now, and give it a try?

In the meantime, I'll submit an enhancement request that we look into working side-by-side with ZoomControls.

map.setOnZoomListener(new OnZoomListener() {
 
 /**
  * 
  */
 private static final long serialVersionUID = 1L;

 @Override
 public void preAction(float pivotX, float pivotY, double factor) {
  // TODO Auto-generated method stub
  
 }
 
 @Override
 public void postAction(float pivotX, float pivotY, double factor) {
  Log.d("test","test of the OnZoomListener");
  
 }
});
0 Kudos
deleted-user-ATjHIWsdQYmT
Occasional Contributor III
Andy,
Thanks for the tip.  I had the same issue as you as far as the callout always hiding.  Any ideas on how to keep it visible when I want it visible, and hidden when I want it hidden?

Thanks,
Andrew
0 Kudos
AndyGup
Esri Regular Contributor
Andrew, do you mean is there a way to control the default callout using my proposed workaround?

I'm not sure what your workflow is, however here's some additional psuedo-code you can try out, and look at bolting some of it into the workaround if it meets your needs. In my app using a pattern like this, I was able to temporarily disable the default callout, and then it would come back the next time a user clicked on a graphic.

Another option would be to create your own custom callout. That would be the best practice, but it would involve more coding.


callout = map.getCallout();
callout.setStyle(R.xml.calloutstyle);

testButton = (ImageButton)findViewById(R.id.testbutton);

testButton.setOnClickListener(new OnClickListener() {
 
 @Override
 public void onClick(View v) {
  if(callout != null){
   callout.hide();
          callout = null; //callout gets re-created when user clicks on Graphic
  }    
 }
});




-Andy
0 Kudos
deleted-user-ATjHIWsdQYmT
Occasional Contributor III
Andy -
Let me see if I can be more clear.  When implementing the listeners you suggest:
Callout is visible.
Click Zoom Out on zoomcontrol
the callout disappears.  I'd like it to stay visible.

This implementation does in fact work properly IF you close the callout before zooming.  But, what if I want it to continue showing while i zoom in/out?  without implementing the listeners the code functions as desired (callout reappears) BUT - you can't keep it closed once it's opened. 

This seems like one of those damned if you do, damned if you don't situations...  I want to be able to use the zoom controls, but I want the callout to stay closed when I close it, and stay open when I have it open.

Thanks again.
0 Kudos
AndyGup
Esri Regular Contributor
How about the following:

Scenario 1 - callout always visible:

Callout is visible.
[set Esri zoom listener to null -- e.g. map.setOnZoomListener(null);]
Click Zoom Out on zoomcontrol
Call should stay visible

Scenario 2 - callout always closed:

Callout is visible.
[user closes callout]
[re-initialize a new Esri zoom listener]
Click Zoom Out on zoomcontrol
the callout disappears.

I haven't tried this but it sounds like it would work. What do you think?

-Andy
0 Kudos
deleted-user-ATjHIWsdQYmT
Occasional Contributor III
Andy,
Worked like a charm....  Toggling the map's zoom listener seemed to be the trick.
For the sake of redundancy, I wrote a method to reinitialize the map's zoom listener.
For those in need, here's my code:

         ZoomControls zoomCtl = (ZoomControls) findViewById(R.id.zoomControls1);  zoomCtl.setOnZoomInClickListener(new View.OnClickListener(){
   @Override
   public void onClick(View v){
    if (callout.isShowing()){
     mMapView.setOnZoomListener(null);
     mMapView.zoomin();
    }else{
    ZoomListenerOn(mMapView);
    mMapView.zoomin();
    }
   }
  });
  zoomCtl.setOnZoomOutClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    if (callout.isShowing()){
     mMapView.setOnZoomListener(null);
     mMapView.zoomout();
    }else{
     ZoomListenerOn(mMapView);
    mMapView.zoomout();
    }
   }
  }); 
public void ZoomListenerOn(MapView m){  m.setOnZoomListener(new OnZoomListener() {
   private static final long serialVersionUID = 1L;
   @Override
   public void preAction(float pivotX, float pivotY, double factor) {
    // TODO Auto-generated method stub
   }
   @Override
   public void postAction(float pivotX, float pivotY, double factor) {
    Log.d("test","test of the OnZoomListener");
   }
  }); 
 }
0 Kudos