views:

497

answers:

2

I currently have implemented an overlayitem that shows an icon for geopoint on a map application in Android. When the icon is clicked, it brings up an AlertDialog from the onTap method below. I have the following questions:

  1. Does anyone know how to display a map message bubble directly above the icon overlayitem with 2 callout buttons one to the left of the title and one to the right of the bubble?
  2. Does anyone know how to make the overlayitem draggable so I can press and hold it and drag it across the map. I am trying to duplicate the draggable icon behavior that's available on the iPhone.

If so, please share some sample code. Thanks

protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet()); dialog.show();
return true; }

+4  A: 

As for #1, you can see how to create popup panels in this sample project from one of my books.

As for #2, I do not believe it is possible, strictly speaking. Certainly, there is nothing built in for that, at least that I have seen. You could attempt to detect a touch event, get rid of the existing overlay item, draw your own copy of the icon where the overlay item had been, manually animate that as the user drags, and then put the overlay item where the user drops it (getting rid of your manually-drawn icon).

CommonsWare
Thanks for your answers. Do you have any sample code to do what you described in #2? deleting overlay item, animating as user drags, and then adding overlay item where the users releases his finger (touch up) event?
Zap
Nope, sorry. I haven't done much with touch other than simple screen taps.
CommonsWare
A: 

Hi CommonsWare

I saw your code, it works fine, in your example.

but I have a mapactivity in tabhost. I am trying your code their. it doesn't show popup, it doesn't throw any error either. did you try your code in tabhost?

Please see my code:

public class FinderHome extends MapActivity  {
Context context=null;
View v=null;
EditText txtSearchPeople=null;
MapView mapFindingResults=null;
List<Overlay> mapOverlays;
Drawable drawable;
MyItemizedOverlay itemizedOverlay;
@Override
public void onCreate(Bundle savedInstanceState)
{
    Log.v("FinderHome", "Activity State: onCreate()");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.finder_home);   
    txtSearchPeople=(EditText) findViewById(R.id.txtSearchPeople);
    mapFindingResults = (MapView) findViewById(R.id.mapFindingResults);
    //mapFindingResults.getController().setZoom(17);
    mapFindingResults.setBuiltInZoomControls(true);
    EditTextKeyListener keyListener=new EditTextKeyListener();
    txtSearchPeople.setOnKeyListener(keyListener);
    mapOverlays = mapFindingResults.getOverlays();
    drawable = this.getResources().getDrawable(R.drawable.androidmarker);
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
            drawable.getIntrinsicHeight());
    itemizedOverlay = new MyItemizedOverlay(drawable,this);     
    LoadResults();
}
private void LoadResults(){
    //my position
    GeoPoint point = new GeoPoint(19240000,-99120000);
    OverlayItem overlayitem = new OverlayItem(point, "Me", "Me");
    itemizedOverlay.addOverlay(overlayitem);
    mapOverlays.add(itemizedOverlay);
    //get list from webservice
    //loop through results and add people
}   
@Override
protected boolean isRouteDisplayed() {
    return false;
}
 //subclass to handle KeyListener event of EditText
private class EditTextKeyListener implements OnKeyListener{
        @Override
           public boolean onKey(View v, int keyCode, KeyEvent event) {
             if ((event.getAction() == KeyEvent.ACTION_UP) && (keyCode == 
                 KeyEvent.KEYCODE_ENTER)) 
                         { 
                 EditText myEditText=(EditText) v;
                 InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                 imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
                         }               
             else if ((event.getAction() == KeyEvent.ACTION_UP) && (keyCode == 
                 KeyEvent.KEYCODE_BACK)) 
                         { 
                 finish();
                         }
            return true;
        }

       } 

public class MyItemizedOverlay extends ItemizedOverlay<OverlayItem> {

    private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
    private Context context=null;
    private PopupPanel panel=new PopupPanel(R.layout.map_popup);        
    public MyItemizedOverlay(Drawable defaultMarker,Context context){
        super(boundCenterBottom(defaultMarker));
        this.context=context;
    }

    public void addOverlay(OverlayItem overlay) {
        mOverlays.add(overlay);
        populate();
    }
    @Override
    protected OverlayItem createItem(int i) {
         return mOverlays.get(i);
    }
    @Override
    protected boolean onTap(int i) {
    //Toast.makeText(context, mOverlays.get(i).getSnippet(), Toast.LENGTH_SHORT).show();
        OverlayItem item=getItem(i);
        GeoPoint geo=item.getPoint();
        Point pt=mapFindingResults.getProjection().toPixels(geo, null);
        View view=panel.getView();
        ((TextView)view.findViewById(R.id.tvBuddyName))
            .setText(item.getSnippet());            
        panel.show(pt.y*2>mapFindingResults.getHeight());
    return(true);
    }
    @Override
    public int size() {
        return mOverlays.size();
    }
}
    class PopupPanel {
        View popup;
        boolean isVisible=false;

        PopupPanel(int layout) {
            ViewGroup parent=(ViewGroup)mapFindingResults.getParent();

            popup=getLayoutInflater().inflate(layout, parent, false);

            popup.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    hide();
                }
            });
        }

        View getView() {
            return(popup);
        }

        void show(boolean alignTop) {
            RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(
                        RelativeLayout.LayoutParams.WRAP_CONTENT,
                        RelativeLayout.LayoutParams.WRAP_CONTENT
            );
            if (alignTop) {
                lp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
                lp.setMargins(0, 20, 0, 0);
            }
            else {
                lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                lp.setMargins(0, 0, 0, 60);
            }
            hide();
            ((ViewGroup)mapFindingResults.getParent()).addView(popup, lp);
            isVisible=true;
        }

        void hide() {
            if (isVisible) {
                isVisible=false;
                ((ViewGroup)popup.getParent()).removeView(popup);
            }
        }
    }

}

Please let me know, if I am doing something wrong. thanks in advance.

Regards, Azam.

Azam Ali