Custom tap window on Google Map

后端 未结 2 1809
盖世英雄少女心
盖世英雄少女心 2020-12-28 10:39

I was just looking at one of the Google map implemented in IPhone which contains labels and buttons.

相关标签:
2条回答
  • 2020-12-28 11:30

    Hi Please check below link may be helpful to you.

    How to display popup on tapping overlay in android?

    also check

    http://android-codes-examples.blogspot.com/2011/04/google-map-example-in-android-with-info.html

    Display multiple markers on Google map

    0 讨论(0)
  • 2020-12-28 11:46

    I have already given the answer of this question but I have also another one it same like you want in the given above image.

    package com.pocketjourney.tutorials;
    import android.os.Bundle;
    import com.google.android.maps.MapActivity;
    
          public class ShowMapWithTappingWindowActivity extends MapActivity {
          @Override
          public void onCreate(Bundle icicle) {
          super.onCreate(icicle);
          setContentView(R.layout.tutorial2);
    }
    
    /**
     * Must let Google know that a route will not be displayed
     */
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    } 
    }
    

    package com.pocketjourney.view;
    import com.google.android.maps.GeoPoint;
        /** Class to hold our location information */
        public class MapLocation {
        private GeoPoint point;
        private String name;
    
    public MapLocation(String name,double latitude, double longitude) {
        this.name = name;
        point = new GeoPoint((int)(latitude*1e6),(int)(longitude*1e6));
    }
    
    public GeoPoint getPoint() {
        return point;
    }
    
    public String getName() {
        return name;
    }
    }
    

        package com.pocketjourney.view;
    
        import java.util.Iterator;
         import java.util.List;
    
         import android.graphics.Bitmap;
         import android.graphics.BitmapFactory;
         import android.graphics.Canvas;
         import android.graphics.Paint;
         import android.graphics.Point;
         import android.graphics.RectF;
         import android.graphics.Paint.Style;
         import android.os.Handler;
         import android.util.Log;
         import android.widget.Toast;
    
         import com.google.android.maps.GeoPoint;
         import com.google.android.maps.MapView;
         import com.google.android.maps.Overlay;
         import com.pocketjourney.tutorials.R;
    
    
           public class MapLocationOverlay  extends Overlay {
    
    //  Store these as global instances so we don't keep reloading every time
          private Bitmap bubbleIcon, shadowIcon,iconForMapKit,iconForMapKitRollOver;
      private Handler mHandler = new Handler();
           private boolean flag = false;
    
           private MapLocationViewer mapLocationViewer;
    
       private Paint    innerPaint, borderPaint, textPaint;
           private Point arrowPointCoordinates = new Point();
       //  The currently selected Map Location...if any is selected.  This tracks whether                                an information  
    //  window should be displayed & where...i.e. whether a user 'clicked' on a known map location
          private MapLocation selectedMapLocation;  
          private int [] start,end ;
            private boolean checkAnimationEnded;
    
    /*
     * The Following method is to be called when to have dropping pin effect
     * the method is simply creating two arrays for starting and ending point of map location.
     * On draw will be called again and again till start point equals the end point
     */
    private void fillYCoordinateArrayForPinDropAnimation(MapLocationViewer  mapLocationViewer)
    { 
        List<MapLocation> mList = mapLocationViewer.getMapLocations();
        int size = mList.size();
        start = new int[size];
        end = new int[size];
    }
    
    /*
     * Method for checking two arrays. Used for dropping pin effect
     */
    private boolean checkTwoArrayForEquality(int [] a , int [] b)
    {
      boolean result = true ;
    
      for(int i = 0 ; i< a.length ; i++)
      {
          if(a[i] < b[i]){ result = false; break; }
      } 
      Log.v("Coor", "Coor Resut = "+ result);
      return result;
    }
    
    public MapLocationOverlay(MapLocationViewer     mapLocationViewer) {
        this.mapLocationViewer = mapLocationViewer;
    
        bubbleIcon = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.marker);
        shadowIcon = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.shadow);
        iconForMapKit = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.arrowformapkit);
        iconForMapKitRollOver = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.arrowformapkit_rollover);
        fillYCoordinateArrayForPinDropAnimation(mapLocationViewer);
    }
    
    @Override
    public boolean onTap(GeoPoint p,final MapView   mapView)  {
    
        //  Store whether prior popup was displayed so we can call invalidate() & remove it if necessary.
        boolean isRemovePriorPopup = selectedMapLocation != null;  
    
        //  Next test whether a new popup should be displayed
        if(moreArrowTappedEvent(mapView,p) && isRemovePriorPopup)
        {
            Toast.makeText(this.mapLocationViewer.getContext(), "I am hit", Toast.LENGTH_LONG).show();
            flag = true;
            mapView.invalidate();
    
            mHandler.postDelayed(new Runnable() {
    
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    flag = false;
                    mapView.invalidate();
                }
            },200L);
    
        }
        else
        {
    
            selectedMapLocation = getHitMapLocation(mapView,p);
            if ( isRemovePriorPopup || selectedMapLocation != null) {
                mapView.invalidate();
            }       
    
    
    
        }   
    
            //  Lastly return true if we handled this onTap()
        return selectedMapLocation != null;
    }
    
    @Override
    public void draw(Canvas canvas, MapView mapView, boolean shadow) {
    
        drawMapLocations(canvas, mapView, shadow);
        drawInfoWindow(canvas, mapView, shadow);
    
        // Uncomment the below for dropping pin effect
    
    
        if(!checkTwoArrayForEquality(start, end))
        {
            for(int i = 0; i<start.length ; i++)
            {
                if(start[i] < end[i] ) start[i]+=3;
            }
            mapView.invalidate();
        }
        else
        {
    
            checkAnimationEnded = true;
        }   
    
    
       }
    
    /**
     * Test whether an information balloon should be displayed or a prior balloon hidden.
     */
    private boolean moreArrowTappedEvent(MapView    mapView, GeoPoint   tapPoint)
    {
        boolean result = false;
    
        RectF hitTestRecr = new RectF();
        Point screenCoords = new Point();
        // Create a 'hit' testing Rectangle w/size and coordinates of our icon
        // Set the 'hit' testing Rectangle with the size and coordinates of our on screen icon
        hitTestRecr.set(arrowPointCoordinates.x,arrowPointCoordinates.y,arrowPointCoordinates.x+iconForMapKit.getWidth(),arrowPointCoordinates.y+iconForMapKit.getHeight());
    
    
        //  Finally test for a match between our 'hit' Rectangle and the location clicked by the user
        mapView.getProjection().toPixels(tapPoint, screenCoords);
        if (hitTestRecr.contains(screenCoords.x,screenCoords.y)) {
            result = true;
        }
        return result;
    
    }
    
    
    
    private MapLocation getHitMapLocation(MapView   mapView, GeoPoint   tapPoint) {
    
        //  Track which MapLocation was hit...if any
        MapLocation hitMapLocation = null;
    
        RectF hitTestRecr = new RectF();
        Point screenCoords = new Point();
        Iterator<MapLocation> iterator = mapLocationViewer.getMapLocations().iterator();
        while(iterator.hasNext()) {
            MapLocation testLocation = iterator.next();
    
            //  Translate the MapLocation's lat/long coordinates to screen coordinates
            mapView.getProjection().toPixels(testLocation.getPoint(), screenCoords);
    
            // Create a 'hit' testing Rectangle w/size and coordinates of our icon
            // Set the 'hit' testing Rectangle with the size and coordinates of our on screen icon
            hitTestRecr.set(-bubbleIcon.getWidth()/2,-bubbleIcon.getHeight(),bubbleIcon.getWidth()/2,0);
            hitTestRecr.offset(screenCoords.x,screenCoords.y);
    
            //  Finally test for a match between our 'hit' Rectangle and the location clicked by the user
            mapView.getProjection().toPixels(tapPoint, screenCoords);
            if (hitTestRecr.contains(screenCoords.x,screenCoords.y)) {
                hitMapLocation = testLocation;
                break;
            }
        }
    
        //  Lastly clear the newMouseSelection as it has now been processed
        tapPoint = null;
    
        return hitMapLocation; 
    }
    
    private void drawMapLocations(Canvas canvas, MapView    mapView, boolean shadow) {
    
        Iterator<MapLocation> iterator = mapLocationViewer.getMapLocations().iterator();
        Point screenCoords = new Point();
    
        int pos = 0; // for drop pin effect 
        while(iterator.hasNext()) {    
            MapLocation location = iterator.next();
            mapView.getProjection().toPixels(location.getPoint(), screenCoords);
            shadow = false ; // remove this line if want shadow to be drawn also.. 
    
            end[pos] = screenCoords.y - bubbleIcon.getHeight();// for drop pin effect
            if (shadow) {
                //  Only offset the shadow in the y-axis as the shadow is angled so the base is at x=0; 
                canvas.drawBitmap(shadowIcon, screenCoords.x, screenCoords.y - shadowIcon.getHeight(),null);
            } 
            else {
                if(checkAnimationEnded)
                {
                    canvas.drawBitmap(bubbleIcon, screenCoords.x - bubbleIcon.getWidth()/2, screenCoords.y - bubbleIcon.getHeight(),null);
                }
                else
                {
                    canvas.drawBitmap(bubbleIcon, screenCoords.x - bubbleIcon.getWidth()/2, start[pos],null); // for drop pin effect
                }   
    
    
                //canvas.drawBitmap(bubbleIcon, screenCoords.x - bubbleIcon.getWidth()/2, screenCoords.y - bubbleIcon.getHeight(),null);
            }
    
            pos++;// for drop pin effect
        }
    }
    
    private void drawInfoWindow(Canvas canvas, MapView  mapView, boolean shadow) {
    
        if ( selectedMapLocation != null) {
            if ( shadow) {
                //  Skip painting a shadow in this tutorial
            } else {
                //  First determine the screen coordinates of the selected MapLocation
                Point selDestinationOffset = new Point();
                mapView.getProjection().toPixels(selectedMapLocation.getPoint(), selDestinationOffset);
    
                //  Setup the info window with the right size & location
                int INFO_WINDOW_WIDTH = 200;
                int INFO_WINDOW_HEIGHT = 50;
                RectF infoWindowRect = new RectF(0,0,INFO_WINDOW_WIDTH,INFO_WINDOW_HEIGHT);             
                int infoWindowOffsetX = selDestinationOffset.x-INFO_WINDOW_WIDTH/2;
                int infoWindowOffsetY = selDestinationOffset.y-INFO_WINDOW_HEIGHT-bubbleIcon.getHeight();
                infoWindowRect.offset(infoWindowOffsetX,infoWindowOffsetY);
    
                //  Draw inner info window
                canvas.drawRoundRect(infoWindowRect, 5, 5, getInnerPaint());
    
                //  Draw border for info window
                canvas.drawRoundRect(infoWindowRect, 5, 5, getBorderPaint());
    
                //  Draw the MapLocation's name
                int TEXT_OFFSET_X = 10;
                int TEXT_OFFSET_Y = 15;
                String name = selectedMapLocation.getName();
                if(name.length() >= 28)
                {
                    name = name.substring(0, 26)+"..";
                }   
                canvas.drawText(name,infoWindowOffsetX+TEXT_OFFSET_X,infoWindowOffsetY+TEXT_OFFSET_Y,getTextPaint());
            //  canvas.drawText(selectedMapLocation.getPrice(),infoWindowOffsetX+TEXT_OFFSET_X,infoWindowOffsetY+TEXT_OFFSET_Y+20,getTextPaint());
                if(!flag)
                {
                    canvas.drawBitmap(iconForMapKit, infoWindowOffsetX+160,infoWindowOffsetY+10, null); 
                }
                else
                {
                    canvas.drawBitmap(iconForMapKitRollOver, infoWindowOffsetX+160,infoWindowOffsetY+10, null);
                }   
    
                arrowPointCoordinates.x = infoWindowOffsetX+160;
                arrowPointCoordinates.y = infoWindowOffsetY+10;
            }
        }
    }
    
    public Paint getInnerPaint() {
        if ( innerPaint == null) {
            innerPaint = new Paint();
            innerPaint.setARGB(225, 75, 75, 75); //gray
            innerPaint.setAntiAlias(true);
        }
        return innerPaint;
    }
    
    public Paint getBorderPaint() {
        if ( borderPaint == null) {
            borderPaint = new Paint();
            borderPaint.setARGB(255, 255, 255, 255);
            borderPaint.setAntiAlias(true);
            borderPaint.setStyle(Style.STROKE);
            borderPaint.setStrokeWidth(2);
        }
        return borderPaint;
    }
    
    public Paint getTextPaint() {
        if ( textPaint == null) {
            textPaint = new Paint();
            textPaint.setARGB(255, 255, 255, 255);
            textPaint.setAntiAlias(true);
        }
        return textPaint;
    }
    }
    

    package com.pocketjourney.view;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.widget.LinearLayout;
    
    import com.google.android.maps.MapView;
    
    public class MapLocationViewer extends LinearLayout {
    
    private MapLocationOverlay overlay;
    
    //  Known latitude/longitude coordinates that we'll be using.
    private List<MapLocation> mapLocations;
    
    private MapView mapView;
    
    public MapLocationViewer(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    
    public MapLocationViewer(Context context) {
        super(context);
        init();
    }
    
    public void init() {        
    
        setOrientation(VERTICAL);
        setLayoutParams(new LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT,android.view.ViewGroup.LayoutParams.FILL_PARENT));
    
        mapView = new MapView(getContext(),"0UHW90ofRVhQWOEMziC6Vn73Fogg9NtCmHCIGGw");
        mapView.setEnabled(true);
        mapView.setClickable(true);
        mapView.setBuiltInZoomControls(true);
        addView(mapView);
    
        overlay = new MapLocationOverlay(this);
        mapView.getOverlays().add(overlay);
    
        mapView.getController().setZoom(14);
        mapView.getController().setCenter(getMapLocations().get(0).getPoint());
    }
    
    public List<MapLocation> getMapLocations() {
        if (mapLocations == null) {
            mapLocations = new ArrayList<MapLocation>();
            mapLocations.add(new MapLocation("North Beach",37.799800872802734,-122.40699768066406));
            mapLocations.add(new MapLocation("China Town",37.792598724365234,-122.40599822998047));
            mapLocations.add(new MapLocation("Fisherman's Wharf",37.80910110473633,-122.41600036621094));
            mapLocations.add(new MapLocation("Financial District",37.79410171508789,-122.4010009765625));
        }
        return mapLocations;
    }
    
    public MapView getMapView() {
        return mapView;
    }
    }
    

    I  have got the fallowing given blow output using the above code same like you want

    I hope you got your answer.

    0 讨论(0)
提交回复
热议问题