web-dev-qa-db-fra.com

Comment déplacer une carte sous un marqueur?

Supposons que nous ayons un marqueur centré sur la carte. Lorsque nous déplaçons la carte avec nos doigts, nous pouvons voir que ce marqueur ne s’affiche plus lorsque vous êtes hors des limites de la zone. Alors, comment pouvons-nous faire un marqueur qui resterait toujours au centre de la carte bien que nous déplacions la carte n'importe où? Il y a une application nommée UBER et ils fournissent cette fonctionnalité, vous ne faites pas glisser le marqueur, vous déplacez simplement la carte et le marqueur est resté sa position.

Voici une capture d'écran:

Uber Map Marker

Comme vous pouvez voir que le marqueur vert est au centre de l'écran lorsque nous déplaçons la carte, il reste à sa place mais indique la nouvelle position lorsque l'utilisateur arrête de déplacer la carte. Comment pouvons-nous faire comme ça?

J'ai un code qui affiche l'adresse lorsque vous faites glisser le marqueur, que diriez-vous d'afficher à nouveau l'adresse, mais cette fois pas en faisant glisser, en déplaçant la carte? J'espère que vous pourrez comprendre toutes les idées seraient géniales.

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

Voici le 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

Deux étapes faciles:

Étape 1

J'ai utilisé un RelativeLayout en tant que parent d'un fragment avec map et centré un ImageView (qui servira de marqueur de carte centré comme dans les applications de taxi simples ou superbes):

<!-- 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>

Étape 2

méthode onMapReady () lors de mon activité, j'utilise la méthode d'instance googleMap setOnCameraChangeListener() qui me permet d'écouter lorsque la carte est utilisée et d'obtenir la latitude et la longitude en fonction du centre de la position de la caméra:

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

}

METTRE À JOUR:
OnCameraChangeListener est obsolète. Veuillez utiliser OnCameraIdleListener:
[Source: https://stackoverflow.com/a/38732283/421467]

27
CommonSenseCode

Je ne pouvais pas obtenir l'effet Uber app, mais je pouvais faire quelque chose de similaire, cela suffirait peut-être à votre solution en utilisant GoogleMap.OnCameraChangeListener .

Activité:

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

    ...

}

Le problème est que le marqueur n'est pas tracé pendant le déplacement de la caméra. Cependant, il semble que vous ayez déjà créé une superposition d'un marqueur. Donc, avec une superposition, cela devrait fonctionner comme l'application Uber. 

J'espère que cela aide, même si la question a quelques mois, peut-être que cela profitera aux futurs développeurs.

Cordialement Miki

10
M1kstur

Si vous utilisez Fragment pour afficher votre carte Google, placez-le ImageView dans la Fragment pour superposer votre marqueur personnalisé de sorte que votre marqueur reste fixe lorsque vous déplacez votre carte. Suivez le code pour le fichier 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>

Dans le fichier activity.Java, utilisez ceci:

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

utilisez setOnCameraChangeListener() pour obtenir la latitude et la longitude en fonction du centre de la position de la caméra ou suivez la réponse fournie par @androidPlusPlus

3
Rudra

Vérifiez ceci réponse

premièrement: ajoutez une image à la même disposition et à la même position que le centre. deuxième: pour obtenir les coordonnées du centre de la carte, utilisez l'approche suivante

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;

Et aussi ici est ma solution complète

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