it-roy-ru.com

Как переместить карту под маркер?

Предположим, что у нас есть центрированный маркер на карте, когда мы перемещаем карту пальцами, мы видим, что маркер больше не будет отображаться, когда вы выйдете за пределы области. Итак, как мы можем сделать маркер, который бы всегда оставался в центре карты, хотя мы перемещаем карту куда угодно? Есть приложение под названием UBER, и они предоставляют эту функцию, вы не перетаскиваете маркер, вы просто перемещаете карту, и маркер остается в своем положении.

Вот скриншот:

Uber Map Marker

Как вы можете видеть, зеленый маркер находится в центре экрана, когда мы перемещаем карту, он остается на своем месте, но показывает новую позицию, когда пользователь прекращает перемещать карту. Как мы можем сделать это?

У меня есть код, который показывает адрес при перетаскивании маркера, как насчет отображения адреса снова, но на этот раз не путем перетаскивания, перемещения карты? Надеюсь, вы поймете, что любые идеи будут великолепны.

public class MainActivity extends AbstractMapActivity implements
    OnNavigationListener, OnInfoWindowClickListener,
    OnMarkerDragListener {
  private static final String STATE_NAV="nav";
  private static final int[] MAP_TYPE_NAMES= { R.string.normal,
    R.string.hybrid, R.string.satellite, R.string.terrain };
  private static final int[] MAP_TYPES= { GoogleMap.MAP_TYPE_NORMAL,
    GoogleMap.MAP_TYPE_HYBRID, GoogleMap.MAP_TYPE_SATELLITE,
    GoogleMap.MAP_TYPE_TERRAIN };
private GoogleMap map=null;
String filterAddress = "";
Marker marker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (readyToGo()) {
        setContentView(R.layout.activity_main);

        SupportMapFragment mapFrag=
            (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);

        mapFrag.setRetainInstance(true);
        initListNav();

        map=mapFrag.getMap();

        if (savedInstanceState == null) {
            CameraUpdate center=
                CameraUpdateFactory.newLatLng(new LatLng(
                        41.003739,
                        28.999572));
            CameraUpdate zoom=CameraUpdateFactory.zoomTo(10);

            map.moveCamera(center);
            map.animateCamera(zoom);

            addMarker(map, 41.003739, 28.999572, R.string.un, R.string.united_nations);

              map.setInfoWindowAdapter(new PopupAdapter(getLayoutInflater()));
              map.setOnInfoWindowClickListener(this);
              map.setOnMarkerDragListener(this);
        }
    }
}

@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
    map.setMapType(MAP_TYPES[itemPosition]);

    return(true);
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);

    savedInstanceState.putInt(STATE_NAV,
            getSupportActionBar().getSelectedNavigationIndex());
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
getSupportActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_NAV));
}

@Override
public void onInfoWindowClick(Marker marker) {
    Toast.makeText(this, marker.getTitle(), Toast.LENGTH_LONG).show();
}

@Override
public void onMarkerDragStart(Marker marker) {
    LatLng position=marker.getPosition();

    Log.d(getClass().getSimpleName(), String.format("Drag from %f:%f",
            position.latitude,
            position.longitude));
}

@Override
public void onMarkerDrag(Marker marker) {
    LatLng position=marker.getPosition();

    Log.d(getClass().getSimpleName(),
            String.format("Dragging to %f:%f", position.latitude,
                    position.longitude));
}

@Override
public void onMarkerDragEnd(Marker marker) {
    LatLng position=marker.getPosition();

    String filterAddress = "";
    Geocoder geoCoder = new Geocoder(
            getBaseContext(), Locale.getDefault());
    try {
        List<Address> addresses = geoCoder.getFromLocation(
                position.latitude, 
                position.longitude, 1);

        if (addresses.size() > 0) {
            for (int index = 0; 
            index < addresses.get(0).getMaxAddressLineIndex(); index++)
                filterAddress += addresses.get(0).getAddressLine(index) + " ";
        }
    }catch (IOException ex) {        
        ex.printStackTrace();
    }catch (Exception e2) {
        // TODO: handle exception
        e2.printStackTrace();
    } 
    Log.d(getClass().getSimpleName(),
            String.format("Dragging to %f:%f", position.latitude,
                    position.longitude));
    TextView myTextView = (TextView) findViewById(R.id.test);

    myTextView.setText("Address is: " + filterAddress);

}

private void initListNav() {
    ArrayList<String> items=new ArrayList<String>();
    ArrayAdapter<String> nav=null;
    ActionBar bar=getSupportActionBar();

    for (int type : MAP_TYPE_NAMES) {
        items.add(getString(type));
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        nav=
            new ArrayAdapter<String>(
                    bar.getThemedContext(),
                    Android.R.layout.simple_spinner_item,
                    items);
    }
    else {
        nav=
            new ArrayAdapter<String>(
                    this,
                    Android.R.layout.simple_spinner_item,
                    items);
    }

    nav.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
    bar.setListNavigationCallbacks(nav, this);
}

private void addMarker(GoogleMap map, double lat, double lon,
        int title, int snippet)

{
    map.addMarker(new MarkerOptions().position(new LatLng(lat, lon))
            .icon(BitmapDescriptorFactory.fromResource(R.drawable.pin))

            .draggable(true));
}
    }

Вот это xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/layout1"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_below="@+id/img_header" >

<fragment
    Android:id="@+id/map"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    class="com.google.Android.gms.maps.SupportMapFragment" />

<TextView
    Android:id="@+id/test"
    Android:layout_width="match_parent"
    Android:layout_height="90dp"
    Android:layout_alignParentRight="true"
    Android:text="Address : "
    Android:textColor="#FF0000"
    Android:textSize="22sp" />
</RelativeLayout>
27
regeme

Два простых шага:

Шаг 1

Я использовал RelativeLayout в качестве родителя фрагмента с картой и центром в нем ImageView (который будет выполнять роль маркера центрированной карты, как в приложениях uber или easy taxi):

<!-- Map and ImageView in center for simulating the map marker -->
<RelativeLayout
    Android:id="@+id/confirm_address_map_wrapper"
    Android:layout_width="match_parent"
    Android:layout_height="220dp">

    <fragment
        Android:id="@+id/confirm_address_map_fragment"
        Android:name="com.google.Android.gms.maps.MapFragment"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_centerInParent="true"
        />
    <!-- Image View that acts as map marker notice centerInParent-->

     <View
        Android:id="@+id/view"
        Android:layout_width="1dp"
        Android:layout_height="1dp"
        Android:layout_centerInParent="true"/>


    <ImageView
        Android:id="@+id/confirm_address_map_custom_marker"
        Android:layout_width="@dimen/ICON_DEFAULT_SIZE"
        Android:layout_height="@dimen/ICON_DEFAULT_SIZE"
        Android:layout_above="@+id/view"
        Android:layout_centerHorizontal="true"
        Android:src="@mipmap/my_map_marker"/>
</RelativeLayout>

Шаг 2

метод onMapReady () в моей деятельности. Я использую метод экземпляра googleMap setOnCameraChangeListener(), который позволяет мне слушать, когда используется карта, и получать широту и долготу на основе центра положения камеры:

    @Override
    public void onMapReady(GoogleMap googleMap) {

        googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
        @Override
        public void onCameraChange(CameraPosition cameraPosition) {

           Log.i("centerLat",cameraPosition.target.latitude);

           Log.i("centerLong",cameraPosition.target.longitude);
        }
    });

}

Обновление:
OnCameraChangeListener устарела. Пожалуйста, используйте OnCameraIdleListener:
[Источник: https://stackoverflow.com/a/38732283/421467]

27
CommonSenseCode

Мне не удалось получить эффект приложения Uber, однако я смог сделать нечто подобное, возможно, оно подойдет для вашего решения, использующего GoogleMap.OnCameraChangeListener .

Деятельность:

public class MyActivity extends Activity implements OnCameraChangeListener {

    ...

    @Override
    public void onCameraChange(CameraPosition position) {
        mMap.clear();
        mMap.addMarker( new MarkerOptions()
            .position( position.target )
            .title( position.toString() )
        );
    }

    ...

}

Проблема в том, что при перемещении камеры маркер не рисуется. Однако кажется, что вы уже создали наложение маркера. Таким образом, с наложением оно должно работать как приложение Uber. 

Надеюсь, это поможет, даже вопросу несколько месяцев, возможно, это пойдет на пользу будущим разработчикам.

С уважением Мики

10
M1kstur

Если вы используете Fragment для отображения своей карты Google, поместите ImageView внутри Fragment, чтобы наложить свой настроенный маркер так, чтобы ваш маркер оставался фиксированным при перемещении карты. Следуйте коду для XML-файла:

<fragment
    Android:id="@+id/map"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    class="com.google.Android.gms.maps.MapFragment" >

    <ImageView
        Android:id="@+id/pin"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="center"
        Android:contentDescription="@null"
        Android:src="@drawable/pin" />
</fragment>

В файле Activity.Java используйте это:

ImageView pinButton = (ImageView) findViewById(R.id.pin);

используйте setOnCameraChangeListener(), чтобы получить широту и долготу на основе центра положения камеры или следуйте ответу, предоставленному @androidPlusPlus

3
Rudra

Проверить это ответить

первое: добавьте вид изображения к тому же макету и расположите его в центре. второе: чтобы получить координату центра карты используйте следующий подход

1_ get viewgroup ( FrameLayout ) in my case where the map fragment is located.

 - FrameLayout myContainer = (FrameLayout) findViewById(R.id.content_frame);
    int mapHeight = myContainer.getHeight();
    int mapWidth = myContainer.getWidth();
2_ use setOnCameraChangeListener and on camera change get the coordinates:

LatLng center = mMap.getCameraPosition().target;

А также здесь это мое полное решение

1
Sishin
mMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
    @Override
    public void onCameraMove() {
        mCurrLocationMarker.remove();
        LatLng midLatLng = mMap.getCameraPosition().target;
        mCurrLocationMarker = mMap.addMarker(new MarkerOptions().title("I am here ").
        position(midLatLng).icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_point));
    }
});

mMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
    @Override
    public void onCameraIdle() {
        mCurrLocationMarker.remove();
        LatLng position = mCurrLocationMarker.getPosition();
        mCurrLocationMarker = mMap.addMarker(new MarkerOptions().title("I am here ").
        position(position).icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_source)));
        getAddress(position.latitude, position.longitude);

    }
});
0
Muhammad Naveed