Google地图上的自定义点按窗口

时间:2011-06-17 12:44:48

标签: android

我只是看着在iPhone中实现的 Google地图之一,其中包含标签和按钮。

enter image description here

如何在Android中获得包含标签,按钮和图像的此类窗口? 请为我提供相同的来源。

2 个答案:

答案 0 :(得分:7)

我已经给出了这个问题的答案,但我还有另外一个与上面给出的图像相同的内容。

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

我希望你得到答案。

答案 1 :(得分:1)