Изменить положение кнопки «Мое местоположение» в 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
Вы смотрели на метод setPadding () GoogleMap? См .: developers.google.com/maps/documentation/android/…
IgorGanapolsky

Ответы:

70

Просто используйте GoogleMap.setPadding (слева, сверху, справа, снизу), который позволяет вам указывать части карты, которые могут быть скрыты другими видами. При установке отступов стандартные элементы управления карты меняются местами, а обновления камеры будут использовать область с заполнением.

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

Аскот Харрис
источник
6
Это лучший ответ. findById (1) - ужасное решение
pablobaldez 08
Абсолютно ясный и лучший практический ответ. Любить это.
josefdlange,
3
Хорошо работает для размещения кнопки mylocation в правом нижнем углу, но, как вы говорите, портит обновления камеры. Как это решить? На данный момент моя камера всегда видит нижнюю часть экрана как центр. Вы добавляете половину высоты экрана к камере при расчетах?
riper 03
4
Я предпочитаю mapView.findViewWithTag ("GoogleMapMyLocationButton"); решение ниже.
ayvazj 06
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);
    }
}
fabLouis
источник
4
Привет @fabLouis, Прежде всего, я хотел тебя поблагодарить. Ваш код переместил LocationButton. Мне просто любопытно, как вы определили идентификатор этой кнопки? Не могли бы вы объяснить об этом подробнее mapView.findViewById(1).getParent()).findViewById(2);? Еще раз спасибо, SH
Swan
4
через отладчик Android Studio
fabLouis
1
если вы сделаете это, Android Studio скажет «ожидаемый ресурс типа id»
inmyth
11
@inmyth Даже у меня такая же ошибка, но я проанализировал 1 и 2, используя класс Integer. findViewById (Integer.parseInt ("1")). Если вы нашли лучшее решение, дайте мне знать.
Harsha
2
хм как RelativeLayout.ALIGN_PARENT_TOPи RelativeLayout.ALIGN_PARENT_BOTTOMровно внизу справа?
user2968401
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) Измените настройки пользовательского интерфейса карт, чтобы кнопка не отображалась при вызове setMyLocationEnabled (true). Вы можете сделать это через map.getUiSettings (). setMyLocationButtonEnabled (ложь);

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
Эта строка - ((Просмотр) mapView.findViewById (1) .getParent ()). FindViewById (2); выдавал мне ошибку - «Ожидаемый ресурс типа ID» для 1 и 2 целых чисел, тогда я решил это следующим образом ((View) mapView.findViewById (Integer.parseInt ("1")). getParent ()). findViewById (Integer .parseInt ("2"));
Зохаб Али
14

Мне не нравится видеть эти идентификаторы волшебных представлений, которые используют другие, я предлагаю использовать теги для поиска MapViewдетей.

Вот мое решение для размещения кнопки « Мое местоположение» над элементами управления масштабированием .

// 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
Привет, Корд, я не знаю, помните ли вы, как это сделать, но помните ли вы, где вы нашли список тегов mapview? Я хочу переместить кое-что другое, и мне действительно не нравятся другие шаблоны, которые используют люди.
Randy
2
@Randy Перебирайте подпредставления MapView (FrameLayout) и регистрируйте теги, чтобы получить их. Смотрите здесь (Написано на Котлине)
ElegyD
@ElegyD Спасибо !!
Randy
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 ();
Md Shihab Uddin
9

Сначала получите Google Map View:

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

Затем найдите кнопку MyLocation (идентификатор из отладчика Android Studio):

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

Наконец, просто установите новые параметры RelativeLayout для кнопки MyLocation (в этом случае выровняйте родительский правый + центр по вертикали):

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
Эта строка - ((Просмотр) mapView.findViewById (1) .getParent ()). FindViewById (2); выдает ошибку - «Ожидаемый ресурс типа ID» для 1 и 2 целых чисел.
zookastos
3
Попробуйте это - View btnMyLocation = ((View) mapView.findViewById (Integer.parseInt ("1")). GetParent ()). FindViewById (Integer.parseInt ("2"));
Silambarasan Poonguti
@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 нельзя преобразовать в android.view.ViewGroup
Наянеш Гупте
8

Если вы просто хотите включить индикацию местоположения (синяя точка), но вам не нужна кнопка Мое местоположение по умолчанию:

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

Таким образом, вы также можете нарисовать свою собственную кнопку там, где хотите, без подобных странных вещей mapView.findViewById(1).getParent()).

Fraggjkee
источник
Большое спасибо
Начо Зулло
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);
}
nobjta_9x_tq
источник
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 много отличных вещей;)
Роман
0

Я добавил строчку в свой фрагмент android: layout_marginTop = "? Attr / actionBarSize" Мне помогло

Олег
источник
0

используйте этот для нижнего правого местоположения

map.setMyLocationEnabled(true); 
map.setPadding(0,1600,0,0);
Муазцисс Наджми
источник