更改Google Maps API的“我的位置”按钮的位置


84

我正在使用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);

2
AFAIK,您没有。您调整布局,使广告不与地图重叠。
CommonsWare

5
您是否看过GoogleMap的setPadding()方法?请参阅:developers.google.com/maps/documentation/android/...
IgorGanapolsky

Answers:


70

只需使用GoogleMap.setPadding(左,上,右,下),它可以指示地图上可能被其他视图遮挡的部分。设置填充会重新定位标准地图控件,并且相机更新将使用填充区域。

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


6
这是最好的答案。findById(1)是一个糟糕的解决方案
pablobaldez 2016年

绝对最清晰,最佳实践的答案。爱它。
josefdlange

3
将mylocation按钮放在右下角时效果很好,但是正如您所说的那样,它会干扰相机更新。怎么解决呢?到目前为止,我的相机始终将屏幕底部视为中心。在计算内容时,是否将屏幕的一半高度加到相机上?
成熟

4
我更喜欢mapView.findViewWithTag(“ GoogleMapMyLocationButton”); 解决方案如下。
ayvazj

3
请注意,setPadding还有许多其他不良后果。最重要的是,它改变了摄像机目标的屏幕位置。
zyamys

87

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

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);
    }
}

4
@fabLouis,您好:首先,我要谢谢您。您的代码确实移动了LocationButton。我只是很好奇,您如何知道该按钮的ID?你能解释更多关于此mapView.findViewById(1).getParent()).findViewById(2);。再次感谢,SH
天鹅

4
通过Android Studio调试器
fabLouis 2014年

1
如果这样做,Android Studio会说“ ID类型的预期资源”
inmyth 2015年

11
@inmyth即使我遇到了相同的错误,但是我使用Integer类解析了1和2。findViewById(Integer.parseInt(“ 1”))。如果您找到了更好的解决方案,请告诉我。
Harsha 2015年

2
嗯如何RelativeLayout.ALIGN_PARENT_TOPRelativeLayout.ALIGN_PARENT_BOTTOM等于右下角?
user2968401 2015年

15

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

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,最好不要在广告上覆盖地图!
瑞安

14

上面已经进行了解释。仅是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);
        }

3
这行-((View)mapView.findViewById(1).getParent())。findViewById(2); 给我一个错误-1和2整数上的“类型ID的预期资源”,然后像这样解决它((View)mapView.findViewById(Integer.parseInt(“ 1”))。getParent())。findViewById(Integer .parseInt(“ 2”));
Zohab Ali

14

我不希望看到其他人正在使用的这些魔术视图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());

3
对于想知道如何对罗盘执行相同操作的人,标记为GoogleMapCompass
zyamys

1
嗨Cord,我不知道您是否记得要怎么做,但是您还记得在哪里找到mapview标签列表吗?我正在寻找其他东西,我真的不喜欢人们使用的其他模式。
兰迪

2
@Randy遍历MapView(FrameLayout)的子视图并记录标签以获取它们。参见此处(科特林撰写)
ElegyD

@ElegyD谢谢!
兰迪

12

我使用以下代码将位置按钮重新定位到视图的右下角,从而解决了地图片段中的此问题,这是我的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,但不适用于我。这是怎么工作的?
Sharath Weaver

您需要像mapView =(View)mapFragment.getView();一样投射(view);
Md Shihab Uddin '18

9

首先,获取Google Map View:

 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);

繁荣!现在您可以根据需要移动它了;)


3
这行-((View)mapView.findViewById(1).getParent())。findViewById(2); 给我一个错误-1和2整数上的“类型ID的预期资源”。
zookastos 2015年

3
试试看-View btnMyLocation =((View)mapView.findViewById(Integer.parseInt(“ 1”))。getParent())。findViewById(Integer.parseInt(“ 2”));
Silambarasan Poonguti 2015年

@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转换

8

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

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

这样,您还可以在所需的位置绘制自己的按钮,而不会出现类似这样的奇怪内容mapView.findViewById(1).getParent())


非常感谢
Nacho Zullo

2

我有同样的问题。我最终使用“层次结构查看器”来识别用于显示按钮的视图并对其进行操作。我知道很骇人,但找不到其他方法。


1
请您分享您的解决方案。
clauziere

2

要使该工作正常,需要进行一些努力。但是我做到了,并且在此过程中还开始移动缩放按钮。这是我的完整代码:

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);
} 
}

2

解决此问题的一种方法。删除默认按钮并创建自己的按钮。在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));
        }
    });

2

试试这个代码

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);
}

2

此按钮移到地图的左侧在此之前,您可以删除旧的按钮规则:

@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);
}

0

您可以使用以下方法:

    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()); 将获得位置视图?
reidisaki

Android Studio调试器中有很多很棒的东西;)
Roman

0

我添加了一行到我的片段 安卓layout_marginTop =“?ATTR / actionBarSize” 它帮助我


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.