webentwicklung-frage-antwort-db.com.de

Wie verschiebe ich eine Karte unter einer Markierung?

Angenommen, wir haben eine zentrierte Markierung auf der Karte. Wenn Sie die Karte mit unseren Fingern bewegen, können Sie feststellen, dass die Markierung nicht mehr angezeigt wird, wenn Sie die Grenzen des Bereichs verlassen. Wie können wir also eine Markierung erstellen, die immer in der Mitte der Karte verbleibt, obwohl wir die Karte irgendwo verschieben? Es gibt eine App namens UBER, die diese Funktion bietet. Sie können die Markierung nicht per Drag & Drop verschieben, sondern nur die Karte verschieben, und die Markierung hat ihre Position beibehalten.

Hier ist ein Screenshot:

Uber Map Marker

Wie Sie sehen, befindet sich der grüne Marker in der Mitte des Bildschirms, wenn wir die Karte verschieben, blieb er an seinem Ort, zeigt jedoch die neue Position, wenn der Benutzer die Karte nicht mehr bewegt. Wie können wir das machen?

Ich habe einen Code, der die Adresse anzeigt, wenn Sie die Markierung ziehen und ablegen. Wie wäre es, wenn Sie die Adresse erneut anzeigen, diesmal jedoch nicht durch Ziehen und Verschieben der Karte? Ich hoffe, Sie können alle Ideen verstehen, wäre großartig.

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

Hier ist die 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

Zwei einfache Schritte:

Schritt 1

Ich habe ein RelativeLayout als übergeordnetes Fragment mit Karte verwendet und in der Mitte eine ImageView (die als zentrierte Kartenmarkierung fungiert, wie in über- oder einfachen Taxi-Apps):

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

Schritt 2

onMapReady () -Methode Bei meiner Aktivität verwende ich die googleMap-Instanzmethode setOnCameraChangeListener(), mit der ich zuhören kann, wenn die Karte verwendet wird, und Breiten- und Längengrad basierend auf der Kameraposition ermitteln:

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

}

UPDATE:
OnCameraChangeListener ist veraltet. Bitte verwenden Sie OnCameraIdleListener:
[Quelle: https://stackoverflow.com/a/38732283/421467]

27
CommonSenseCode

Ich konnte den Uber-App-Effekt nicht erhalten, jedoch war ich in der Lage, etwas Ähnliches zu tun. Möglicherweise ist dies für Ihre Lösung gut, wenn Sie die GoogleMap.OnCameraChangeListener verwenden.

Aktivität:

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

    ...

}

Das Problem ist, dass die Markierung nicht gezeichnet wird, während die Kamera bewegt wird. Es scheint jedoch, als hätten Sie bereits eine Überlagerung eines Markers erstellt. Mit einem Overlay sollte es also wie die Uber-Anwendung funktionieren. 

Ich hoffe, das hilft, auch wenn die Frage ein paar Monate alt ist, vielleicht kommt sie zukünftigen Entwicklern zugute.

Herzliche Grüße Miki

10
M1kstur

Wenn Sie Fragment verwenden, um Ihre Google-Karte anzuzeigen, setzen Sie die ImageView in die Fragment, um Ihre benutzerdefinierte Markierung so zu überlagern, dass die Markierung beim Verschieben der Karte unverändert bleibt. Folgen Sie dem Code für die XML-Datei:

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

Verwenden Sie in der Datei "activity.Java" Folgendes:

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

verwenden Sie setOnCameraChangeListener(), um den Breiten- und Längengrad basierend auf der Kameraposition zu ermitteln, oder folgen Sie der Antwort von @androidPlusPlus

3
Rudra

Überprüfen Sie diese Antwort

erstens: Fügen Sie eine Bildansicht zu demselben Layout und derselben Position wie in der Mitte hinzu. Zweitens: Um die Koordinate der Kartenmitte zu erhalten, gehen Sie wie folgt vor

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;

Und auch hier ist meine Komplettlösung

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