我正在创建一个Android应用程序,该应用程序将在Google地图上显示多个用户的位置。用户当前在地图上表示为蓝色和绿色点。当您点按代表您所在位置的蓝点时,地图上会显示一个自定义叠加层,上面显示“当前位置”
我的问题是,当我滚动或缩放地图时,当地图移动到地图下方时,带有“当前位置”的叠加层仍保留在同一位置。我希望它与地图一起移动,以便弹出窗口始终直接位于蓝点上方,如下例所示:
http://econym.org.uk/gmap/example_ewindow.htm。
以下是我的地图项目的布局方式:
我有一个扩展com.google.android.maps.MapActivity的Activity。此活动的成员是com.google.android.maps.MapView对象。我使用AdjacentMapOverlayList(扩展ItemizedOverlay)来管理叠加层。
当用户点击蓝色图标时,这是我的代码:
/*
* Handle tap events.
*
* @param index the item that was tapped
*/
@Override
protected boolean onTap(int index) {
Log.d(TAG, "User clicked something");
// get the item that was tapped
OverlayItem item = (OverlayItem) getItem(index);
// cast it
AdjacentUserOverlay overlay = (AdjacentUserOverlay) item;
// get the point from the item
GeoPoint geo = overlay.getPoint();
Point pt = m_mapView.getProjection().toPixels(geo, null);
// display the dialog
m_userPopupDialog.show(pt.x, pt.y);
// true dat
return true;
}
我猜我需要拦截地图移动事件并手动移动弹出对话框,但必须有一种更简单的方法。任何人都可以解释如何做到这一点?如果您需要任何其他信息,我会整天待在。谢谢你的建议!
答案 0 :(得分:1)
我明白了。这是我的课程,它扩展了com.google.android.maps.Overlay:
package com.joshuawitter.maps;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.Log;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
import com.joshuawitter.Base64;
/*
* UsersOverlay.java
*
* Description: The Google Maps overlay that displays the users on the map screen.
*
* Author: Joshua Witter
*/
public class UsersOverlay extends Overlay {
private static final String TAG = "Josh-UsersOverlay";
// the activity that called this overlay
private Activity m_caller;
// the currently selected User
private UserOnMap m_selectedUser;
// list of User locations
private ArrayList<UserOnMap> m_Users;
// set the list of Users
public void setUsers(ArrayList<UserOnMap> users) {
// set the list of Users
this.m_Users = users;
}
/*
* Parameterized constructor.
*
* @param caller the activity that created this overlay
* @param Users a list of the Users to display
*/
public UsersOverlay(Activity caller) {
super();
// reference the caller
m_caller = caller;
// make a new list of Users
m_Users = new ArrayList<UserOnMap>(0);
}
/*
* User tapped the map.
*
* @param geoPoint the location the user tapped
* @param mapView the map itself
*/
@Override
public boolean onTap(GeoPoint geoPoint, MapView mapView) {
// get the User that was tapped
UserOnMap user = getTappedUser(mapView, geoPoint);
// if the user tapped on a User
if (null != user) {
// if this User is not already selected, select it
m_selectedUser = (m_selectedUser != user) ? user : null;
}
// otherwise the user tapped nothing
else {
// deselect the selected user
m_selectedUser = null;
}
// call through to the parent
return super.onTap(geoPoint, mapView);
}
/*
* Draw the overlay on the map.
*
* @param canvas the canvas to draw on
* @param mapView the map view
* @param shadow should we draw the shadow?
*/
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
// draw the User icons
drawUserIcons(canvas, mapView);
// call the parent draw method
super.draw(canvas, mapView, shadow);
}
/*
* Draw the User icons on the map.
*
* @param canvas the canvas to draw on
* @param mapView the map view
*/
private void drawUserIcons(Canvas canvas, MapView mapView) {
// loop through the users
for (UserOnMap user : m_Users) {
// draw the icon for the User
drawUserIcon(canvas, mapView, user);
}
// draw the selected User last so that it is on top
if (null != m_selectedUser) {
drawUserBubble(canvas, mapView, m_selectedUser);
}
}
/*
* Draw a User bubble overlay.
*
* @param canvas the canvas to draw on
* @param mapView the map view
* @param user the User we are displaying the information for
*/
private void drawUserBubble(Canvas canvas, MapView mapView, UserOnMap user) {
// get the overlay point
Projection projection = mapView.getProjection();
Point pt = new Point();
projection.toPixels(user.getLocation(), pt);
// get the bubble bitmap ready
Bitmap bubbleBitmap = BitmapFactory
.decodeResource(m_caller.getResources(),
R.drawable.user_bubble);
// get the dimensions of the bubble
int height = bubbleBitmap.getHeight();
int width = bubbleBitmap.getWidth();
// calculate the offsets
int xValue = pt.x - (width / 2);
int yValue = pt.y - height - 20;
// draw the icon
canvas.drawBitmap(bubbleBitmap, xValue, yValue, null);
// get the paint object
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setTextSize(24);
// draw the text
canvas.drawText("Current Location", xValue + 30, yValue + 33, paint);
}
/*
* Draw a User icon overlay.
*
* @param canvas the canvas to draw on
* @param mapView the map view
* @param user the User we are displaying the icon for
*/
private void drawUserIcon(Canvas canvas, MapView mapView,
UserOnMap user) {
// get the overlay point
Projection projection = mapView.getProjection();
Point pt = new Point();
projection.toPixels(user.getLocation(), pt);
// get the icon
Bitmap icon = BitmapFactory.decodeResource(m_caller.getResources(),
user.getIconResource());
// get the dimensions of the icon
int height = icon.getHeight();
int width = icon.getWidth();
// calculate the offsets
int xValue = pt.x - (width / 2);
int yValue = pt.y - height;
// draw the icon
canvas.drawBitmap(icon, xValue, yValue, null);
}
/*
* Determine which User was tapped by the user.
*
* @param tapPoint where the user tapped
* @param mapView the map view
* @param UserOnMap the User was tapped, null if none
*/
private UserOnMap getTappedUser(MapView mapView, GeoPoint tapPoint) {
// get the screen coordinates that match our tap
Point tapScreenCoordinates = new Point();
mapView.getProjection().toPixels(tapPoint, tapScreenCoordinates);
// loop through the User icons
for (UserOnMap user : m_Users) {
// if this is the currently selected User
if (user == m_selectedUser) {
// if we tapped its bubble
if (hitUserBubble(mapView, tapPoint, user)) {
// we found the User
Log.d(TAG, "User " + user.getLastName() + " was tapped (bubble)");
return user;
}
}
// otherwise if we tapped the icon for an User
if (hitUserIcon(mapView, tapPoint, user)) {
// return the User
Log.d(TAG, "User " + user.getLastName() + " was tapped (icon)");
return user;
}
}
// return the tapped User
return null;
}
/*
* Determine if an User's icon was tapped by the user.
*
* @param tapPoint where the user tapped
* @param mapView the map view
* @param User the User we are checking
* @param boolean true if the icon for this User was tapped
*/
private boolean hitUserIcon(MapView mapView, GeoPoint tapPoint,
UserOnMap user) {
// get the screen coordinates that match our tap
Point tapScreenCoordinates = new Point();
mapView.getProjection().toPixels(tapPoint, tapScreenCoordinates);
// get the screen coordinates for the User's location
Point iconScreenCoordinates = new Point();
mapView.getProjection().toPixels(user.getLocation(),
iconScreenCoordinates);
// get the icon for the User
Bitmap icon = BitmapFactory.decodeResource(m_caller.getResources(),
user.getIconResource());
// calculate the icon hit box size
int xValue = 50;
int yValue = 50;
// create a rectangle representing our icon
RectF iconRectangle = new RectF();
iconRectangle.set(-xValue, -yValue, xValue, yValue);
iconRectangle.offset(iconScreenCoordinates.x, iconScreenCoordinates.y);
// return true if the user tapped on the icon for this User
return (iconRectangle.contains(tapScreenCoordinates.x,
tapScreenCoordinates.y));
}
/*
* Determine if an User's bubble was tapped by the user.
*
* @param tapPoint where the user tapped
* @param mapView the map view
* @param User the User we are checking
* @param boolean true if the bubble for this User was tapped
*/
private boolean hitUserBubble(MapView mapView, GeoPoint tapPoint,
UserOnMap user) {
// get the screen coordinates that match our tap
Point tapScreenCoordinates = new Point();
mapView.getProjection().toPixels(tapPoint, tapScreenCoordinates);
// get the screen coordinates for the User's location
Point iconScreenCoordinates = new Point();
mapView.getProjection().toPixels(user.getLocation(),
iconScreenCoordinates);
// get the bubble for the User
Bitmap bubble = BitmapFactory.decodeResource(m_caller.getResources(),
R.drawable.backup_map_current_location);
// calculate the bubble hit box size
int xValue = bubble.getWidth() * 2;
int yValue = bubble.getHeight() * 2;
// create a rectangle representing our bubble
RectF iconRectangle = new RectF();
iconRectangle.set(-xValue, -yValue, xValue, yValue);
iconRectangle.offset(iconScreenCoordinates.x, iconScreenCoordinates.y);
// return true if the user tapped on the bubble
return (iconRectangle.contains(tapScreenCoordinates.x,
tapScreenCoordinates.y));
}
}
我有一个由我的活动(扩展MapActivity)调用的服务,该服务返回用户列表。我只是拿这个列表并使用这个方法:
// for each User we got back
for (User user: response.getUsers()) {
// get the location of the User
GeoPoint userLocation = new GeoPoint(
(int) (user.getLatitude() * 1E6),
(int) (user.getLongitude() * 1E6));
// create a map representation of the User
UserOnMap userOnMap = new UserOnMap(user.getUserId(),
user.getFirstName(), user.getLastName());
// add the user to the list
usersOnMap.add(userOnMap);
}
// set the overlay to reference this new list
m_usersOverlay.setUsers(usersOnMap);
// get the current list of map overlays
List<Overlay> m_mapOverlays = m_mapView.getOverlays();
m_mapOverlays.clear();
m_mapOverlays.add(m_usersOverlay);
m_mapView.invalidate();
如果您有任何疑问,请与我们联系。请忽略循环中的分配,奇怪的变量名称等,这不仅是粗略的草稿,而且是混淆的: - )