如何移动Android Google Maps API指南针位置

26

有人知道如何在地图中更改指南针的位置吗?

我只能找到如何启用或禁用它的方法。但我需要将它向下移动一点,这样我的覆盖层就不会遮挡它了。

enter image description here

10个回答

20

1
不是一个好的解决方案,在缩放到您的位置时,您的位置也将在底部。 - Tigran Babajanyan

14
@Override
public void onMapReady(GoogleMap map) {

    try {
        final ViewGroup parent = (ViewGroup) mMapView.findViewWithTag("GoogleMapMyLocationButton").getParent();
        parent.post(new Runnable() {
            @Override
            public void run() {
                try {
                    Resources r = getResources();
                    //convert our dp margin into pixels
                    int marginPixels = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());
                    // Get the map compass view
                    View mapCompass = parent.getChildAt(4);

                    // create layoutParams, giving it our wanted width and height(important, by default the width is "match parent")
                    RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(mapCompass.getHeight(),mapCompass.getHeight());
                    // position on top right
                    rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
                    rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
                    rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                    rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0);
                    //give compass margin
                    rlp.setMargins(marginPixels, marginPixels, marginPixels, marginPixels);
                    mapCompass.setLayoutParams(rlp);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
    } catch (Exception ex) {
        ex.printStackTrace();
    }

}

4

我知道这个问题已经存在很长时间了,但是几天前我遇到了同样的问题,我像下面这样解决了它:

try {
                assert mapFragment.getView() != null;
                final ViewGroup parent = (ViewGroup) mapFragment.getView().findViewWithTag("GoogleMapMyLocationButton").getParent();
                parent.post(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            for (int i = 0, n = parent.getChildCount(); i < n; i++) {
                                View view = parent.getChildAt(i);
                                RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) view.getLayoutParams();
                                // position on right bottom
                                rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
                                rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP,0);
                                rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                                rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                                rlp.rightMargin = rlp.leftMargin;
                                rlp.bottomMargin = 25;
                                view.requestLayout();
                            }
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                });
            } catch (Exception ex) {
                ex.printStackTrace();
            }

在这个例子中,我把指南针放在右下角。当您执行此操作时,请确保您的mapFragment已经创建好了,我建议您在MapFragment的"onMapReady"方法中运行代码。


1
由于某种原因,这被放置在左下角! - Paschalis
现在是2023年,它仍然可以正常工作。 - djdance

3
我知道你不能更改指南针位置,但你可以禁用它并构建自己的私人指南针。 查看示例请点击这里

+1 有趣。让我们看看是否有人想出解决方法,如果没有,那么所有的功劳都归你。 - capdragon
但是这是使用MapView。对于MapFragment有什么想法吗? - Nayanesh Gupte
将片段包含到活动布局中,它将与MapView相同工作。 - Alpha

2

最好使用以下代码片段:

mapView.findViewWithTag<View>("GoogleMapCompass")?.let { compass ->
    compass.post {
        val topMargin = compass.marginTop
        val rlp = RelativeLayout.LayoutParams(compass.height, compass.height)
        rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0)
        rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP)
        rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
        rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0)

        val endMargin = (4 * Resources.getSystem().displayMetrics.density).toInt()
        rlp.setMargins(0, topMargin, endMargin, 0)
        compass.layoutParams = rlp
    }
}

这样你就不必使用"GoogleMapMyLocationButton"并遍历其父级。遍历父级没有任何好处,并且在未来谷歌提供地图视图更新时更容易出现问题。 在这段代码片段中,直接访问罗盘,这是你需要的元素。


目前您的回答不太清楚。请编辑并补充更多详细信息,以便他人了解如何解决问题。您可以在 帮助中心 中找到有关如何编写良好答案的更多信息。 - Community

1

根据@Vignon的答案(https://dev59.com/8GUp5IYBdhLWcg3wzpxk#38266867),这里是一个Kotlin代码片段,用于将指南针图标定位到屏幕右上角。 您还可以添加自定义边距(在此示例中,指南针图像具有50dp的marginTop)。

mapFragment?.view?.let { mapView ->
  mapView.findViewWithTag<View>("GoogleMapMyLocationButton").parent?.let { parent ->
    val vg: ViewGroup = parent as ViewGroup
    vg.post {
      val mapCompass: View = parent.getChildAt(4)
      val rlp = RelativeLayout.LayoutParams(mapCompass.height, mapCompass.height)
      rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0)
      rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP)
      rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
      rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0)

      val topMargin = (50 * Resources.getSystem().displayMetrics.density).toInt()
      rlp.setMargins(0, topMargin, 0, 0)    
      mapCompass.layoutParams = rlp
    }
  }
 }

1

基于填充的解决方案适用于小偏移量,但据我所知,没有公开的API允许我们像原生Google Maps应用程序一样稳健地改变指南针的水平“重力”从左到右:

enter image description here

请注意,如果您在自己的应用程序中应用了大量的左填充来将指南针移动到右侧,则左下角的Google标志也会向右移动。

1
在2.0地图API上。
        // change compass position 
    if (mapView != null &&
            mapView.findViewById(Integer.parseInt("1")) != null) {
        // Get the view
        View locationCompass = ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("5"));
        // and next place it, on bottom right (as Google Maps app)
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
                locationCompass.getLayoutParams();
        // position on right bottom
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
        layoutParams.setMargins(0, 160,30, 0); // 160 la truc y , 30 la  truc x
    }

0
这是我的解决方案。
首先,我需要使用Kotlin扩展来获取任何视图的所有子视图。
fun View.getAllChildren(): List<View> {
    val result = ArrayList<View>()
    if (this !is ViewGroup) {
        result.add(this)
    } else {
        for (index in 0 until this.childCount) {
            val child = this.getChildAt(index)
            result.addAll(child.getAllChildren())
        }
    }
    return result
}

接下来,我只需通过查找其内容描述来检索指南针(如果内容描述在将来更改,请使用布局检查器进行检索)。

当您拥有视图时,可以像这样更改其位置:

    binding.mapView
            .getAllChildren()
            .firstOrNull { it.contentDescription == "Compass" }
            ?.let { it.y = it.y + 400 }

0

跟随 @Vignon herre 的建议,在 Kotlin 中将指南针放在左下角:

            mapFragment.view?.let { mapView->
                mapView.findViewWithTag<View>("GoogleMapMyLocationButton").parent?.let { parent->
                    val vg: ViewGroup = parent as ViewGroup
                    vg.post {
                        val mapCompass :View = parent.getChildAt(4)
                        val rlp = RelativeLayout.LayoutParams(mapCompass.height, mapCompass.height)
                        rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
                        rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP,0)
                        rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,0)
                        rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)

                        val bottomMargin = (40 * Resources.getSystem().displayMetrics.density).toInt()
                        val leftMargin = (5 * Resources.getSystem().displayMetrics.density).toInt()
                        rlp.setMargins(leftMargin,0,0,bottomMargin)
                        mapCompass.layoutParams = rlp
                    }
                }
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接