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:
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>
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>
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]
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
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
Ü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
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);
}
});