【问题标题】:Change position of Google Maps API's "My location" button更改 Google Maps API 的“我的位置”按钮的位置
【发布时间】:2013-01-07 12:46:36
【问题描述】:

我正在使用 Google Maps Android API v2,我需要一种方法来确定“我的位置”按钮的位置。

我得到这样的“我的位置”按钮:

GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
final GoogleMap map = ((SupportMapFragment) getSupportFragmentManager()
        .findFragmentById(R.id.map)).getMap();

// This gets the button
map.setMyLocationEnabled(true);

【问题讨论】:

标签: java android google-maps-android-api-2 android-maps-v2


【解决方案1】:

您可以获取“我的位置”按钮并移动它,例如:

public class MapFragment extends SupportMapFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View mapView = super.onCreateView(inflater, container, savedInstanceState);   

    // Get the button view 
    View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2);

    // and next place it, for exemple, on bottom right (as Google Maps app)
    RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
    // position on right bottom
    rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
    rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
    rlp.setMargins(0, 0, 30, 30);
    }
}

【讨论】:

  • 嗨@fabLouis,首先,我要感谢你。您的代码确实移动了 LocationButton。我只是好奇你是怎么知道那个按钮的 ID 的?你能解释更多关于这个mapView.findViewById(1).getParent()).findViewById(2);。再次感谢,SH
  • 通过 Android Studio 调试器
  • 如果你这样做,Android Studio 会说“expected resource of type id”
  • @inmyth 即使我遇到了同样的错误,但我使用 Integer 类解析了 1 和 2。 findViewById(Integer.parseInt("1"))。如果您找到了更好的解决方案,请告诉我。
  • hmm RelativeLayout.ALIGN_PARENT_TOPRelativeLayout.ALIGN_PARENT_BOTTOM 怎么在右下角相等?
【解决方案2】:

只需使用 GoogleMap.setPadding(left, top, right, bottom),它允许您指示地图中可能被其他视图遮挡的部分。设置填充会重新定位标准地图控件,并且相机更新将使用填充区域。

https://developers.google.com/maps/documentation/android/map#map_padding

【讨论】:

  • 这是最好的答案。 findById(1) 是一个糟糕的解决方案
  • 绝对最清晰和最佳实践的答案。喜欢它。
  • 非常适合将 mylocation 按钮放在右下角,但正如您所说,它会扰乱相机更新。如何解决?到目前为止,我的相机始终将屏幕底部视为中心。计算东西时,是否将屏幕高度的一半添加到相机?
  • 我更喜欢 mapView.findViewWithTag("GoogleMapMyLocationButton");下面的解决方案。
  • 请注意,setPadding 有许多其他可能不受欢迎的副作用。最重要的是,它改变了相机目标的屏幕位置。
【解决方案3】:

这可能不是最佳解决方案,但您可以将自己的按钮放在地图上并自行处理。它需要以下内容:-

1) 将地图放入 frameLayout 并在顶部添加按钮。例如

<FrameLayout
    android:id="@+id/mapFrame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >



    <fragment
        xmlns:map="http://schemas.android.com/apk/res-auto"
        android:id="@+id/mapFragment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        class="com.google.android.gms.maps.MapFragment"
        map:mapType="normal"
        map:uiCompass="true" />

    <ImageButton
        android:id="@+id/myMapLocationButton"
        android:layout_width="36dp"
        android:layout_height="36dp"
        android:layout_gravity="bottom|right"
        android:background="@drawable/myMapLocationDrawable"
        android:contentDescription="My Location" />

</FrameLayout>

2) 编辑地图 UI 设置,这样当您调用 setMyLocationEnabled(true) 时按钮不会出现。您可以通过 map.getUiSettings() 执行此操作。 setMyLocationButtonEnabled(false);

3) 处理新按钮的单击以模拟提供的按钮的作用。例如。调用 mmap.setMyLocationEnabled(...);并将地图平移到当前位置。

希望对您有所帮助,或者希望有人为您提供更简单的解决方案;-)

【讨论】:

  • 顺便说一句,我同意 CommonsWare 的观点,最好不要用广告覆盖地图!
【解决方案4】:

上面已经解释过了。只是对 fabLouis 回答的一个小补充。 您也可以从 SupportMapFragment 获取地图视图。

        /**
         * Move the button
         */
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().
                findFragmentById(R.id.map);
        View mapView = mapFragment.getView();
        if (mapView != null &&
                mapView.findViewById(1) != null) {
            // Get the button view
            View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2);
            // and next place it, on bottom right (as Google Maps app)
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
                    locationButton.getLayoutParams();
            // position on right bottom
            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
            layoutParams.setMargins(0, 0, 30, 30);
        }

【讨论】:

  • 这一行 - ((View) mapView.findViewById(1).getParent()).findViewById(2);给了我一个错误 - 1和2整数上的“类型ID的预期资源”然后我像这样解决它 ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer .parseInt("2"));
【解决方案5】:

我不喜欢看到其他人正在使用的这些神奇视图 ID,我建议使用标签来查找 MapViews 孩子。

这是我将我的位置按钮放在缩放控件上方的解决方案。

// Get map views
View location_button =_mapView.findViewWithTag("GoogleMapMyLocationButton");
View zoom_in_button = _mapView.findViewWithTag("GoogleMapZoomInButton");
View zoom_layout = (View) zoom_in_button.getParent();

// adjust location button layout params above the zoom layout
RelativeLayout.LayoutParams location_layout = (RelativeLayout.LayoutParams) location_button.getLayoutParams();
location_layout.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
location_layout.addRule(RelativeLayout.ABOVE, zoom_layout.getId());

【讨论】:

  • 对于任何想知道如何为指南针做同样事情的人,标签是GoogleMapCompass
  • 嘿Cord,我不知道你是否记得如何做到这一点,但你记得你在哪里找到了mapview标签列表吗?我正在寻找一些其他的东西,我真的不喜欢人们使用的其他模式。
  • @Randy 遍历 MapView (FrameLayout) 的子视图并记录标签以获取它们。请参阅here(用 Kotlin 编写)
  • @ElegyD 谢谢!!
【解决方案6】:

我通过使用下面的代码将我的位置按钮重新定位到视图的右下角解决了我的地图片段中的这个问题,这是我的 Maps Activity.java :-

在 onCreate() 方法中添加这行代码,

 SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapView = mapFragment.getView();
        mapFragment.getMapAsync(this);

这里是 onMapReady() 代码:-

@Override
        public void onMapReady(GoogleMap googleMap) {
            mMap = googleMap;
            mMap.setMyLocationEnabled(true);

            // Add a marker in Sydney and move the camera
            LatLng sydney = new LatLng(-34, 151);
            mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
            mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));

            if (mapView != null &&
                    mapView.findViewById(Integer.parseInt("1")) != null) {
                // Get the button view
                View locationButton = ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
                // and next place it, on bottom right (as Google Maps app)
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
                        locationButton.getLayoutParams();
                // position on right bottom
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
                layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
                layoutParams.setMargins(0, 0, 30, 30);
            }

        }

希望这能解决您的问题。谢谢。

【讨论】:

  • 感谢为我工作。我只尝试使用 ALIGN_PARENT_BOTTOM 但对我不起作用。这是如何工作的?
  • 你需要像 mapView = (View)mapFragment.getView(); 一样投射(视图);
【解决方案7】:

首先,获取谷歌地图视图:

 View mapView = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getView();

然后找到 MyLocation 按钮(来自 Android Studio 调试器的 ID):

 View btnMyLocation = ((View) mapView.findViewById(1).getParent()).findViewById(2);

最后,只需为 MyLocation 按钮设置新的 RelativeLayout 参数(在这种情况下对齐父右侧 + 垂直居中):

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(80,80); // size of button in dp
    params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
    params.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
    params.setMargins(0, 0, 20, 0);
    btnMyLocation.setLayoutParams(params);

轰隆隆!现在你可以随意移动它了;)

【讨论】:

  • 这一行 - ((View) mapView.findViewById(1).getParent()).findViewById(2);给我一个错误 - 1 和 2 整数上的“类型 ID 的预期资源”。
  • 试试这个 - 查看 btnMyLocation = ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
  • @Nalin 如果您在错误上按 Alt-Enter 以禁用检查(例如方法),则有一个选项。
【解决方案8】:

请参阅下面的方法。它存在于扩展 SupportMapFragment 的类中。它获取按钮的容器视图并将其显示在底部,水平居中。

/**
     * Move my position button at the bottom of map
     */
    private void resetMyPositionButton()
    {
        //deep paths for map controls
        ViewGroup v1 = (ViewGroup)this.getView();
        ViewGroup v2 = (ViewGroup)v1.getChildAt(0);
        ViewGroup v3 = (ViewGroup)v2.getChildAt(0);
        ViewGroup v4 = (ViewGroup)v3.getChildAt(1);

        //my position button
        View position =  (View)v4.getChildAt(0);

        int positionWidth = position.getLayoutParams().width;
        int positionHeight = position.getLayoutParams().height;

        //lay out position button
        RelativeLayout.LayoutParams positionParams = new RelativeLayout.LayoutParams(positionWidth,positionHeight);
        int margin = positionWidth/5;
        positionParams.setMargins(0, 0, 0, margin);
        positionParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
        positionParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
        position.setLayoutParams(positionParams);
    }

【讨论】:

  • 它给了我 java.lang.ClassCastException: maps.af.q cannot be cast to android.view.ViewGroup
【解决方案9】:

如果您只想启用位置指示(蓝点)但不需要默认的“我的位置”按钮:

mGoogleMap.setMyLocationEnabled(true);
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);

这样你也可以在你想要的地方绘制你自己的按钮,而不需要像mapView.findViewById(1).getParent())这样的奇怪东西。

【讨论】:

  • 非常感谢
【解决方案10】:

我遇到了同样的问题。我最终使用 Hierarchy Viewer 来识别用于显示按钮的视图并对其进行操作。很老套,我知道,但想不出其他方法。

【讨论】:

  • 请分享您的解决方案。
【解决方案11】:

让这个工作有点困难。但我完成了,在这个过程中也开始移动缩放按钮。这是我的完整代码:

package com.squirrel.hkairpollution;

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.UiSettings;
import com.google.android.gms.maps.model.LatLng;

public class MySupportMapFragment extends SupportMapFragment {

private static final String TAG = HKAirPollution.TAG;

public MySupportMapFragment() {
    return;
}

@Override
public View onCreateView(LayoutInflater arg0, ViewGroup arg1, Bundle arg2) {
    Log.v(TAG, "In overridden onCreateView.");
    View v = super.onCreateView(arg0, arg1, arg2);
    Log.v(TAG, "Initialising map.");
    initMap();
    return v;
}

@Override
 public void onViewCreated (View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    resetButtons();
}

private void initMap(){
    UiSettings settings = getMap().getUiSettings();
    settings.setAllGesturesEnabled(true);
    settings.setMyLocationButtonEnabled(true);
    LatLng latLong = new LatLng(22.320542, 114.185715);
    getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(latLong,11));
}


/**
 * Move my position button at the bottom of map
 */
private void resetButtons()
{
    // Get a reference to the zoom buttons and the position button.
    ViewGroup v1 = (ViewGroup)this.getView();
    ViewGroup v2 = (ViewGroup)v1.getChildAt(0);
    ViewGroup v3 = (ViewGroup)v2.getChildAt(0);
    ViewGroup v4 = (ViewGroup)v3.getChildAt(1);

    // The My Position button
    View position =  (View)v4.getChildAt(0);
    int positionWidth = position.getLayoutParams().width;
    int positionHeight = position.getLayoutParams().height;

    // Lay out the My Position button.
    RelativeLayout.LayoutParams positionParams = new RelativeLayout.LayoutParams(positionWidth,positionHeight);
    int margin = positionWidth/5;
    positionParams.setMargins(0, 0, 0, margin);
    positionParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
    positionParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
    position.setLayoutParams(positionParams);

    // The Zoom buttons
    View zoom = (View)v4.getChildAt(2);
    int zoomWidth = zoom.getLayoutParams().width;
    int zoomHeight = zoom.getLayoutParams().height;

    // Lay out the Zoom buttons.
    RelativeLayout.LayoutParams zoomParams = new RelativeLayout.LayoutParams(zoomWidth, zoomHeight);
    zoomParams.setMargins(0, 0, 0, margin);
    zoomParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
    zoomParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
    zoom.setLayoutParams(zoomParams);
} 
}

【讨论】:

    【解决方案12】:

    解决此问题的一种方法。删除默认按钮并创建自己的。 在 OnCreate 语句中添加下一个:

    GoogleMap mMap = ((MapView) inflatedView.findViewById(R.id.mapview)).getMap();
    LocationManager locationManager =    
    (LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    String provider = locationManager.getBestProvider(criteria, false);
    Location location = locationManager.getLastKnownLocation(provider);
    locationManager.requestLocationUpdates(provider, 2000, 1,  this);
    
    mMap.setMyLocationEnabled(true);
    mMap.getUiSettings().setMyLocationButtonEnabled(false); // delete default button
    
    Imagebutton imgbtn = (ImageButton) view.findViewById(R.id.imgbutton); //your button
    imgbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new    
    LatLng(location.getLatitude(),     
    location.getLongitude()), 15));
            }
        });
    

    【讨论】:

      【解决方案13】:

      试试这个代码

      private void resetMyPositionButton()
      {
          Fragment fragment = ( (SupportMapFragment) getSupportFragmentManager().findFragmentById( R.id.map ) );
          ViewGroup v1 = (ViewGroup) fragment.getView();
          ViewGroup v2 = (ViewGroup)v1.getChildAt(0);
          ViewGroup v3 = (ViewGroup)v2.getChildAt(2);
          View position =  (View)v3.getChildAt(0);
          int positionWidth = position.getLayoutParams().width;
          int positionHeight = position.getLayoutParams().height;
      
          //lay out position button
          RelativeLayout.LayoutParams positionParams = new RelativeLayout.LayoutParams(positionWidth,positionHeight);
          int margin = positionWidth/5;
          positionParams.setMargins(margin, 0, 0, margin);
          positionParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
          positionParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
          position.setLayoutParams(positionParams);
      }
      

      【讨论】:

        【解决方案14】:

        之前,您可以删除按钮的旧规则:

        @Override
        public void onMapReady(final GoogleMap googleMap) {
            this.map = googleMap;
            // Show location button
            View locationButton = ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
            RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
            // position on right bottom
            Log.l(Arrays.toString(rlp.getRules()), L.getLogInfo());
            int[] ruleList = rlp.getRules();
            for (int i = 0; i < ruleList.length; i ++) {
                rlp.removeRule(i);
            }
            Log.l(Arrays.toString(rlp.getRules()), L.getLogInfo());
            //Do what you want to move this location button:
            rlp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
            rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
        }
        

        【讨论】:

          【解决方案15】:

          您可以使用以下方法:

              View myLocationParent = ((View) getView().findViewById(1).getParent());
              View myLocationParentParent = ((View) myLocationParent.getParent());
          
              // my position button
          
              int positionWidth = myLocationParent.getLayoutParams().width;
              int positionHeight = myLocationParent.getLayoutParams().height;
          
              // lay out position button
              FrameLayout.LayoutParams positionParams = new FrameLayout.LayoutParams(
                      positionWidth, positionHeight);
              positionParams.setMargins(0, 100, 0, 0);
          
              myLocationParent.setLayoutParams(positionParams);
          

          【讨论】:

          • 你怎么知道的 ((View) getView().findViewById(1).getParent());会得到位置视图吗?
          • Android Studio 调试器中有很多很棒的东西 ;)
          【解决方案16】:

          我在片段中添加了一行 android:layout_marginTop="?attr/actionBarSize" 它帮助了我

          【讨论】:

            【解决方案17】:

            将此用于右下角的位置

            map.setMyLocationEnabled(true); 
            map.setPadding(0,1600,0,0);
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-08-23
              • 1970-01-01
              • 1970-01-01
              • 2020-03-09
              • 1970-01-01
              • 1970-01-01
              • 2016-08-15
              相关资源
              最近更新 更多