package org.osmdroid.overlays; // TODO composite view as texture overlay and only allow one bubble at a time. import org.oscim.view.MapView; import android.content.Context; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; /** * View that can be displayed on an OSMDroid map, associated to a GeoPoint. * Typical usage: cartoon-like bubbles displayed when clicking an overlay item. * It mimics the InfoWindow class of Google Maps JavaScript API V3. Main * differences are: * <ul> * <li>Structure and content of the view is let to the responsibility of the * caller.</li> * <li>The same InfoWindow can be associated to many items.</li> * </ul> * Known issues: * <ul> * <li>It disappears when zooming in/out (osmdroid issue #259 on osmdroid 3.0.8, * should be fixed in next version).</li> * <li>The window is displayed "above" the marker, so the queue of the bubble * can hide the marker.</li> * </ul> * This is an abstract class. * @see DefaultInfoWindow * @author M.Kergall */ public abstract class InfoWindow { protected View mView; protected boolean mIsVisible = false; protected MapView mMapView; protected RelativeLayout mLayout; private android.widget.RelativeLayout.LayoutParams mLayoutPos; /** * @param layoutResId * the id of the view resource. * @param mapView * the mapview on which is hooked the view */ public InfoWindow(int layoutResId, MapView mapView) { mMapView = mapView; mIsVisible = false; ViewGroup parent = (ViewGroup) mapView.getParent(); Context context = mapView.getContext(); LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); mView = inflater.inflate(layoutResId, parent, false); RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams( android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.MATCH_PARENT); mLayout = new RelativeLayout(context); mLayout.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); mLayout.setLayoutParams(rlp); mLayoutPos = rlp; // not so sure about this. why is just blitting the bitmap on glview so slow?... mView.setDrawingCacheEnabled(true); // mLayout.setDrawingCacheEnabled(true); // mLayout.setPersistentDrawingCache(ViewGroup.PERSISTENT_ALL_CACHES); // mLayout.setAlwaysDrawnWithCacheEnabled(true); // call this method mLayout.setWillNotDraw(true); mLayout.addView(mView); } /** * Returns the Android view. This allows to set its content. * @return the Android view */ public View getView() { return (mView); } /** * open the window at the specified position. * @param item * the item on which is hooked the view * @param offsetX * (&offsetY) the offset of the view to the position, in pixels. * This allows to offset the view from the marker position. * @param offsetY * ... */ public void open(ExtendedOverlayItem item, int offsetX, int offsetY) { onOpen(item); close(); // if it was already opened // mView.requestLayout(); mView.buildDrawingCache(); mMapView.addView(mLayout); mIsVisible = true; } public void position(int x, int y) { // if this isnt madness... RelativeLayout.LayoutParams rlp = mLayoutPos; rlp.leftMargin = x; rlp.rightMargin = -x; rlp.topMargin = -y; rlp.bottomMargin = y + mMapView.getHeight() / 2; mLayout.setLayoutParams(rlp); //mMapView.requestLayout(); mLayout.requestLayout(); // using scrollTo the bubble somehow does not appear when it // is not already in viewport... // mLayout.scrollTo(-x, y + mMapView.getHeight() / 2); } public void close() { if (mIsVisible) { mIsVisible = false; ((ViewGroup) mLayout.getParent()).removeView(mLayout); onClose(); } } public boolean isOpen() { return mIsVisible; } // Abstract methods to implement: public abstract void onOpen(ExtendedOverlayItem item); public abstract void onClose(); }