Thay đổi vị trí của nút “Vị trí của tôi” của API Google Maps


84

Tôi đang sử dụng Google Maps Android API v2 và tôi cần một cách để xác định vị trí của nút "Vị trí của tôi".

Tôi nhận được nút "Vị trí của tôi" như sau:

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

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

2
AFAIK, bạn không. Bạn điều chỉnh bố cục của mình để quảng cáo không chồng lên bản đồ.
CommonsWare

5
Bạn đã xem phương thức setPadding () của GoogleMap chưa? Xem: Developers.google.com/maps/documentation/android/…
IgorGanapolsky

Câu trả lời:


70

Chỉ cần sử dụng GoogleMap.setPadding (trái, trên, phải, dưới), cho phép bạn chỉ ra các phần của bản đồ có thể bị che khuất bởi các chế độ xem khác. Đặt vùng đệm sẽ định vị lại các điều khiển bản đồ tiêu chuẩn và cập nhật máy ảnh sẽ sử dụng vùng đệm.

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


6
Đây là câu trả lời tốt nhất. findById (1) là một giải pháp khủng khiếp
pablobaldez

Câu trả lời tuyệt đối rõ ràng nhất và thực hành tốt nhất. Yêu nó.
josefdlange

3
Hoạt động tốt khi đặt nút định vị ở góc dưới bên phải, nhưng như bạn nói, nó làm rối tung các bản cập nhật máy ảnh. Làm thế nào để giải quyết điều đó? Hiện tại, máy ảnh của tôi luôn xem phần dưới của màn hình là trung tâm. Bạn có thêm một nửa chiều cao của màn hình vào máy ảnh khi tính toán nội dung không?
riper

4
Tôi thích mapView.findViewWithTag ("GoogleMapMyLocationButton"); giải pháp bên dưới.
ayvazj

3
Lưu ý rằng setPaddingcó rất nhiều tác dụng phụ khác có thể không mong muốn. Quan trọng nhất, nó thay đổi vị trí màn hình của mục tiêu máy ảnh.
zyamys

87

Bạn có thể lấy nút "Vị trí của tôi" và di chuyển nó, như:

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
Xin chào @fabLouis, Trước hết, tôi muốn cảm ơn bạn. Mã của bạn đã di chuyển LocationButton. Tôi chỉ tò mò rằng làm thế nào bạn tìm ra Id của nút đó? Bạn có thể giải thích thêm về điều này mapView.findViewById(1).getParent()).findViewById(2);. Cảm ơn một lần nữa, SH
Swan

4
qua trình gỡ lỗi Android Studio
fabLouis

1
nếu bạn thực hiện việc này, Android Studio sẽ thông báo "tài nguyên dự kiến ​​của loại id"
inmyth 20/02/15

11
@inmyth Ngay cả tôi cũng gặp lỗi tương tự, nhưng tôi đã phân tích cú pháp 1 và 2 bằng cách sử dụng lớp Số nguyên. findViewById (Integer.parseInt ("1")). Nếu bạn đã tìm thấy giải pháp tốt hơn, hãy cho tôi biết.
Harsha

2
hmm như thế nào RelativeLayout.ALIGN_PARENT_TOPRelativeLayout.ALIGN_PARENT_BOTTOMđáy bằng nhau phải không?
user2968401

15

Đây có thể không phải là giải pháp tốt nhất, nhưng bạn có thể đặt nút của riêng mình trên bản đồ và tự xử lý. Nó sẽ diễn ra như sau: -

1) Đặt bản đồ trong frameLayout và thêm nút của bạn lên trên. Ví dụ

<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) Chỉnh sửa cài đặt giao diện người dùng bản đồ để nút không xuất hiện khi bạn gọi setMyLocationEnabled (true). Bạn có thể thực hiện việc này thông qua map.getUiSettings (). setMyLocationButtonEnabled (false);

3) Xử lý việc nhấp vào nút mới của bạn để mô phỏng chức năng của nút được cung cấp. Ví dụ: gọi mMap.setMyLocationEnabled (...); và xoay bản đồ đến vị trí hiện tại.

Hy vọng điều đó có ích, hoặc hy vọng ai đó lâu dài với một giải pháp đơn giản hơn cho bạn ;-)


BTW cho những gì nó đáng giá Tôi đồng ý với CommonsWare, không che bản đồ với một quảng cáo sẽ là tốt nhất!
Ryan

14

Nó đã được giải thích ở trên, chỉ là một bổ sung nhỏ cho câu trả lời của fabLouis. Bạn cũng có thể xem bản đồ của mình từ 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
Dòng này - ((Xem) mapView.findViewById (1) .getParent ()). FindViewById (2); đã gây cho tôi lỗi - "Tài nguyên mong đợi của loại ID" trên số nguyên 1 và 2 sau đó tôi đã giải quyết nó như thế này ((Xem) mapView.findViewById (Integer.parseInt ("1")). getParent ()). findViewById (Integer .parseInt ("2"));
Zohab Ali

14

Tôi không thích nhìn những ID chế độ xem ảo diệu này mà người khác đang sử dụng, tôi khuyên bạn nên sử dụng thẻ để tìm MapViewcon của chúng.

Đây là giải pháp của tôi để đặt nút Vị trí của tôi phía trên các điều khiển Thu phóng .

// 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
Đối với bất kỳ ai tự hỏi làm thế nào để làm điều tương tự cho la bàn, thẻ là GoogleMapCompass.
zyamys

1
Này Cord, tôi không biết bạn có nhớ cách làm điều này không, nhưng bạn có nhớ bạn đã tìm thấy danh sách các thẻ mapview ở đâu không? Tôi đang tìm cách di chuyển một số thứ khác xung quanh và tôi thực sự không thích những mẫu khác mà mọi người đang sử dụng.
Randy

2
@Randy Lặp lại thông qua các lần xem phụ của MapView (FrameLayout) và ghi nhật ký của thẻ để lấy chúng. Xem ở đây (Viết bằng Kotlin)
ElegyD

@ElegyD Cảm ơn bạn !!
Randy

12

Tôi đã giải quyết vấn đề này trong phân đoạn bản đồ của mình bằng cách định vị lại nút vị trí của tôi ở góc dưới cùng bên phải của chế độ xem bằng cách sử dụng mã bên dưới, đây là Hoạt động trên bản đồ của tôi.java: -

thêm dòng mã này trong phương thức onCreate (),

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

và đây là mã 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);
            }

        }

Tôi hy vọng, điều này sẽ giải quyết vấn đề của bạn. Cảm ơn.


Cảm ơn đã làm việc cho tôi. Tôi chỉ thử với ALIGN_PARENT_BOTTOM nhưng không hiệu quả với tôi. cái này hoạt động như thế nào
Sharath Weaver vào

bạn cần truyền (xem) như mapView = (Xem) mapFragment.getView ();
Md Shihab Uddin

9

Đầu tiên, tải Google Map View:

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

Sau đó tìm nút MyLocation (id từ trình gỡ lỗi Android Studio):

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

Cuối cùng, chỉ cần thiết lập các thông số RelativeLayout mới cho nút MyLocation (căn chỉnh chính giữa bên phải + chính giữa theo chiều dọc trong trường hợp này):

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

Bùm! Bây giờ bạn có thể di chuyển nó như bạn muốn;)


3
Dòng này - ((Xem) mapView.findViewById (1) .getParent ()). FindViewById (2); đang cho tôi lỗi - "Tài nguyên mong đợi của loại ID" trên số nguyên 1 và 2.
zookastos

3
Hãy thử điều này - Xem btnMyLocation = ((Xem) mapView.findViewById (Integer.parseInt ("1")). GetParent ()). FindViewById (Integer.parseInt ("2"));
Silambarasan Poonguti

@Nalin Có một tùy chọn nếu bạn Alt-Enter vào lỗi để tắt kiểm tra (ví dụ: đối với phương pháp).
Richard Le Mesurier vào

8

Xem phương pháp bên dưới. Nó nằm bên trong một lớp mở rộng SupportMapFragment. Nó nhận được chế độ xem vùng chứa cho nút và hiển thị nó ở dưới cùng, căn giữa theo chiều ngang.

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

nó đem lại cho tôi java.lang.ClassCastException: maps.af.q không thể được đúc để android.view.ViewGroup
Nayanesh Gupte

8

Nếu bạn chỉ muốn bật chỉ báo vị trí (chấm màu xanh lam) nhưng không cần nút Vị trí của tôi mặc định:

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

Bằng cách này, bạn cũng có thể vẽ nút của riêng mình ở nơi bạn muốn mà không cần những thứ lạ lùng như thế này mapView.findViewById(1).getParent()).


Cảm ơn bạn rất nhiều
Nacho Zullo

2

Tôi đã từng gặp vấn đề tương tự. Cuối cùng tôi đã sử dụng Trình xem thứ bậc để xác định chế độ xem được sử dụng để hiển thị nút và thao tác với nó. Rất khó, tôi biết, nhưng không thể tìm ra cách khác.


1
Bạn có thể chia sẻ giải pháp của bạn xin vui lòng.
clauziere

2

Đó là một chút khó khăn để làm cho nó hoạt động. Nhưng tôi đã hoàn thành, và trong quá trình này, tôi cũng bắt đầu di chuyển các nút thu phóng xung quanh. Đây là mã hoàn chỉnh của tôi:

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

Một cách để đối phó với vấn đề này. Xóa nút mặc định và tạo nút của riêng bạn. Trong câu lệnh OnCreate, thêm đoạn tiếp theo:

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

thử mã này

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

Nút này đã được chuyển sang phía bên trái của bản đồTrước đây, bạn có thể xóa quy tắc cũ của nút:

@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

Bạn có thể sử dụng cách tiếp cận sau:

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

làm thế nào bạn biết rằng ((Xem) getView (). findViewById (1) .getParent ()); sẽ có được chế độ xem vị trí?
reidisaki

Có rất nhiều thứ tuyệt vời trong trình gỡ lỗi Android Studio;)
Roman

0

Tôi đã thêm một dòng vào phân mảnh android: layout_marginTop = "? Attr / actionBarSize" Nó đã giúp tôi


0

sử dụng cái này cho vị trí dưới cùng bên phải

map.setMyLocationEnabled(true); 
map.setPadding(0,1600,0,0);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.