当前位置: 首页 > 知识库问答 >
问题:

谷歌地图Android API-如何在拖动时移动标记的定位点

李睿
2023-03-14

在Android上的Google地图上拖动标记时,标记显示在手指下方,这使得几乎不可能准确地将标记放置在地图上。有没有办法简单地将标记移到顶部一些像素以使其可见?

我尝试在markerdragstart()中移动标记,但当我继续拖动时,它会立即返回到原来的位置。我还尝试在markerdrag()中不断移动标记位置。这会在停止拖动标记时产生不可预测的结果。

是否有官方方法在拖动标记时移动标记,或者是否有人找到了其他方法?

共有2个答案

公西国发
2023-03-14

以下是基本步骤,下面是完整代码。经过测试,效果很好。

首先,假设我们使用的是标记图标位图,大小为27像素乘27像素,并且您希望将锚点从图标的默认左下角移动到右下角。
将锚点移动到右下角:marker.setAnchor(1,0);
x方向的一个图标宽度为27 DP,但我们需要知道这是多少像素。
offsetPoint. x-=MapUtils.convertDpToPx(CreateRouteActivity.this, offsetDPX);
现在我们知道屏幕上的点在哪里,所以只需从中获取LatLng:marker.set位置(projection.fromScreenloc(offsetPoint));如果您想移动图标离你的手指更远,只需尝试ANCHOR_FACTOR值。

以下是我的CreateRouteActivity:

private GoogleMap.OnMarkerDragListener onMarkerDragListener = new GoogleMap.OnMarkerDragListener() {
        float offsetDPX;
        float offsetDPY;
        Projection projection;

        @Override
        public void onMarkerDragStart(Marker marker) {
            // Save the projection every time a marker starts to drag. This keeps the anchors and drop points synced up.
            // If we don't save the projection at the point the marker starts to drag and the user zooms out, the icon pixel size
            // will remain the same but the LatLng distances will have way fewer pixels, messing up the drop point.
            projection = gMap().getProjection();

            // GoogleMap's default anchor is located at the lower left point of the marker icon.
            // An ANCHOR_FACTOR of 1 will move the drag point to the lower right of the icon.
            // An ANCHOR_FACTOR of 2 will move the drag point to the lower right x 2. (The icon will move from under the user's finger to 2 width's above and to the left.)
            float ANCHOR_FACTOR = 1f;
            // 27 is my original icon's width in pixels. 
            // Android increases the pixel size of the image in high-density screens, so make sure you use 27 DPs, not 27 pixels.
            offsetDPX = 27*ANCHOR_FACTOR; 
            offsetDPY = 27*(ANCHOR_FACTOR-1);
            // Always set the anchor by percentage of icon width. 0,0 is lower left. 1,0 is lower right.
            marker.setAnchor(ANCHOR_FACTOR,ANCHOR_FACTOR-1); 
        }

        @Override
        public void onMarkerDrag(Marker marker) {
            // If you want something to happen while you drag, put it here.
        }

        @Override
        public void onMarkerDragEnd(Marker marker) {
            // getPosition returns pixel location
            Point offsetPoint = projection.toScreenLocation(marker.getPosition());
            // We need to offset by the number of DPs, so convert DPs to pixels.
            offsetPoint.x -= MapUtils.convertDpToPx(CreateRouteActivity.this, offsetDPX); 
            offsetPoint.y -= MapUtils.convertDpToPx(CreateRouteActivity.this, offsetDPY);

            // set the marker's LatLng from offsetPoint (in pixels)
            marker.setPosition(projection.fromScreenLocation(offsetPoint));
    };

以及我的MapUtils对象中的一些转换工具:

    public static float convertDpToPx(Context context, float dp) {
        return dp * context.getResources().getDisplayMetrics().density;
    }

    public static float convertPxToDp(Context context, float px) {
        return px / context.getResources().getDisplayMetrics().density;
    }
齐财
2023-03-14

我自己也对此很感兴趣,所以我尝试了很多方法。

我最终发现,默认情况下,Maps API会在开始拖动标记时按其宽度向右移动标记。要在拖动后伪造[1,1]锚点,我们需要将标记向左水平(x轴)移动其宽度,并向上垂直(y轴)移动其高度。

这种方式似乎工作正常,非常整洁。

这里有一个例子:

// Get marker dimensions
Bitmap img = BitmapFactory.decodeResource(getResources(), R.drawable.marker);
final int width = img.getWidth();
final int height = img.getHeight();

mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
    @Override
    public void onMarkerDragStart(final Marker marker) {
        marker.setAnchor(1, 1);
    }

    @Override
    public void onMarkerDrag(Marker marker) {

    }

    @Override
    public void onMarkerDragEnd(final Marker marker) {
        Projection projection = mMap.getProjection();
        // Coordinates to point (in screen pixels)
        Point point = projection.toScreenLocation(marker.getPosition());
        // Move to [1, 1]
        point.x -= width;
        point.y -= height;
        // Point to coordinates
        LatLng coords = projection.fromScreenLocation(point);
        // Reset the anchor and use the coordinates
        marker.setAnchor(0, 0);
        marker.setPosition(coords);
    }
});

// Your marker
BitmapDescriptor bitmapDescriptor =
        BitmapDescriptorFactory.fromResource(R.drawable.marker);

mMap.addMarker(new MarkerOptions()
        .position(mPolylines.get(0).getPoints().get(1000))
        .icon(bitmapDescriptor)
        .anchor(0, 0)
        .draggable(true));

注意:这个答案表明你可能需要等待地图完全膨胀,然后才能使用地图的投影。你可能想相应地编辑,尽管我发现没有它也能正常工作。

 类似资料:
  • 我试图写一个地理位置网页,显示用户在地图上的大致位置。如果他们点击标记,他们可以把它拖到他们的确切位置。

  • 我成功创建了一个活动,用户可以在其中发布他的状态并将他的当前位置放置在android工作室中创建的google map中。我还尝试在map中查看所有其他用户,我成功地做到了。但是,随着他们的位置发生变化,不断增加。我想实现这样一种情况,即用户在移动时可以在地图上看到彼此,并且这些也会相应地移动。我使用Firebase作为我的后端来存储他们的位置和状态。这是我想出的代码。 请帮帮我!提前感谢!:)

  • 我使用Google Maps Android SDK在地图上添加标记,这些标记的位置存储在我的应用程序的所有用户都可以使用的Firebase数据库中。每个标记的数据存储在唯一的Firebase记录中,每个记录包含纬度 添加了一个新标记。 更改现有标记(移动到新位置和/或“验证”) 删除现有标记 我实现了一个哈希图,如如何使用Firebase Google Maps API Android中的数据更

  • 我在做一个从传感器收集数据的应用程序。每次传感器发送数据时,地图上都会放置一个新的标记。当我按后退,然后恢复地图活动,所有的标记都消失了。在恢复活动时,是否有方法保存和恢复每个唯一的标记及其唯一的标记选项(title、snippet、LatLng)?

  • 我需要一些帮助来绘制我正在绘制的地图。地图并不特别复杂,因为我是一个初学者,我有一堆带有信息窗口的标记(完成后还会有更多标记),单击标记或选择页面HTML端下拉菜单的相应项时可以打开这些标记。 当信息窗口打开时(在HTML菜单中单击或选择),我想做但自己找不到的是在地图上自动居中标记。我假设有某种函数可以分配给click或infowindow打开事件,但无法确定是哪种函数以及如何实现它。 我的代码

  • 我在我的flutter应用程序中使用google_maps_flutter来使用谷歌地图我有自定义标记图标,我用BitmapDescriptor.from字节(mark erIcon)加载它,但我想用一些文本显示Url的图标。 这就是我们要达到的目的 是否可以通过flutter或任何可以动态创建图像的外部图像依赖来实现相同的效果。