Google 地图 - 在地图中显示多个标记
Google Maps - Show many markers in a map
我已经尝试了一段时间在地图中显示多个标记,但我一直 运行 出错。
我设法想出了这段代码,但我遇到了崩溃。
这是我的 mapsActivity.java
package com.example.moses.ngongapp;
import android.app.Dialog;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.view.ViewTreeObserver;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.ArrayList;
import java.util.HashMap;
public class MapsActivity extends FragmentActivity {
private GoogleMap googleMap;
private ArrayList<LatLng> listLatLng;
private RelativeLayout rlMapLayout;
HashMap<Marker, LatLngBean> hashMapMarker = new HashMap<Marker, LatLngBean>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
rlMapLayout = (RelativeLayout) findViewById(R.id.rlMapLayout);
setUpMapIfNeeded();
setData();
}
private void setData() {
ArrayList<LatLngBean> arrayList = new ArrayList<LatLngBean>();
LatLngBean bean = new LatLngBean();
bean.setTitle("Ahmedabad");
bean.setSnippet("Hello,Ahmedabad");
bean.setLatitude("23.0300");
bean.setLongitude("72.5800");
arrayList.add(bean);
LatLngBean bean1 = new LatLngBean();
bean1.setTitle("Surat");
bean1.setSnippet("Hello,Surat");
bean1.setLatitude("21.1700");
bean1.setLongitude("72.8300");
arrayList.add(bean1);
LatLngBean bean2 = new LatLngBean();
bean2.setTitle("Vadodara");
bean2.setSnippet("Hello,Vadodara");
bean2.setLatitude("22.3000");
bean2.setLongitude("73.2000");
arrayList.add(bean2);
LoadingGoogleMap(arrayList);
}
/**
* @author Hasmukh Bhadani
* Set googleMap if require
*/
private void setUpMapIfNeeded() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
// Google Play Services are not available
if (status != ConnectionResult.SUCCESS) {
int requestCode = 10;
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
dialog.show();
} else if (googleMap == null) {
((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMapAsync((OnMapReadyCallback) this);
if (googleMap != null) {
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
}
}
}
/**
* @author Hasmukh Bhadani
* Loading Data to the GoogleMap
*/
// -------------------------Google Map
void LoadingGoogleMap(ArrayList<LatLngBean> arrayList) {
if (googleMap != null) {
googleMap.clear();
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
if (arrayList.size() > 0) {
try {
listLatLng = new ArrayList<LatLng>();
for (int i = 0; i < arrayList.size(); i++) {
LatLngBean bean = arrayList.get(i);
if (bean.getLatitude().length() > 0 && bean.getLongitude().length() > 0) {
double lat = Double.parseDouble(bean.getLatitude());
double lon = Double.parseDouble(bean.getLongitude());
Marker marker = googleMap.addMarker(new MarkerOptions()
.position(new LatLng(lat, lon))
.title(bean.getTitle())
.snippet(bean.getSnippet())
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
//Add Marker to Hashmap
hashMapMarker.put(marker, bean);
//Set Zoom Level of Map pin
LatLng object = new LatLng(lat, lon);
listLatLng.add(object);
}
}
SetZoomlevel(listLatLng);
} catch (NumberFormatException e) {
e.printStackTrace();
}
googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker position) {
LatLngBean bean = hashMapMarker.get(position);
Toast.makeText(getApplicationContext(), bean.getTitle(), Toast.LENGTH_SHORT).show();
}
});
}
} else {
Toast.makeText(getApplicationContext(), "Sorry! unable to create maps", Toast.LENGTH_SHORT).show();
}
}
/**
* @author Hasmukh Bhadani
* Set Zoom level all pin withing screen on GoogleMap
*/
public void SetZoomlevel(ArrayList<LatLng> listLatLng) {
if (listLatLng != null && listLatLng.size() == 1) {
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(listLatLng.get(0), 10));
} else if (listLatLng != null && listLatLng.size() > 1) {
final LatLngBounds.Builder builder = LatLngBounds.builder();
for (int i = 0; i < listLatLng.size(); i++) {
builder.include(listLatLng.get(i));
}
final ViewTreeObserver treeObserver = rlMapLayout.getViewTreeObserver();
treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
if (googleMap != null) {
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), findViewById(R.id.map)
.getWidth(), findViewById(R.id.map).getHeight(), 80));
rlMapLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
}
}
}
我的logcat在这里
FATAL EXCEPTION: main
Process: com.example.moses.ngongapp, PID: 28132
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.moses.ngongapp/com.example.moses.ngongapp.MapsActivity}: java.lang.ClassCastException: com.example.moses.ngongapp.MapsActivity cannot be cast to com.google.android.gms.maps.OnMapReadyCallback
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.access0(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5371)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:945)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:740)
Caused by: java.lang.ClassCastException: com.example.moses.ngongapp.MapsActivity cannot be cast to com.google.android.gms.maps.OnMapReadyCallback
at com.example.moses.ngongapp.MapsActivity.setUpMapIfNeeded(MapsActivity.java:90)
at com.example.moses.ngongapp.MapsActivity.onCreate(MapsActivity.java:44)
@Override
public void onMapReady(GoogleMap map) {
this.googleMap = map;
setUpMapIfNeeded();
setData()
}
在onMapReady()
中做地图相关的事情。
此处出错
((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMapAsync((OnMapReadyCallback) this);
错误清楚地写着“MapsActivity cannot be cast to com.google.android.gms.maps.OnMapReadyCallback
”。
所以,只需实现该接口
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
并从该接口实现相应的 onMapReady
方法。
那你就不用施法了。只是 getMapAsync(MapsActivity.this)
在该方法之内或之后之前,也不要执行任何 GoogleMap
相关功能。
关于您的评论,您必须跟踪您的代码以确切说明 if (googleMap != null) {
未被输入的原因。因为地图是空的 - 显然。但为什么?因为 getMapAsync
将 "wait" 直到地图准备就绪,此时 getMapAsync
在未来某个不确定的点被调用(因此异步,它在后台运行)。
换句话说,不要在onCreate中调用setUpMapIfNeeded或setData方法,而是仅在地图可用时调用(从参数到onMapReady方法)
@Override
public void onMapReady(GoogleMap map) {
this.googleMap = map;
setUpMapIfNeeded();
setData(); // this calls LoadingGoogleMap()
}
如果标记仍然不可见,请继续调试您的代码。该答案仅用于解决问题中提到的错误。
顺便说一句,your previous question was already implementing the interface
您可以实施 onMapReady 等新方法以及有关该方法的其余工作。
((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).
getMapAsync(new OnMapReadyCallback()
@Override
public void onMapReady(GoogleMap map) {
this.googleMap = map;
setUpMapIfNeeded();
setData()
});
我已经尝试了一段时间在地图中显示多个标记,但我一直 运行 出错。
我设法想出了这段代码,但我遇到了崩溃。
这是我的 mapsActivity.java
package com.example.moses.ngongapp;
import android.app.Dialog;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.view.ViewTreeObserver;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.ArrayList;
import java.util.HashMap;
public class MapsActivity extends FragmentActivity {
private GoogleMap googleMap;
private ArrayList<LatLng> listLatLng;
private RelativeLayout rlMapLayout;
HashMap<Marker, LatLngBean> hashMapMarker = new HashMap<Marker, LatLngBean>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
rlMapLayout = (RelativeLayout) findViewById(R.id.rlMapLayout);
setUpMapIfNeeded();
setData();
}
private void setData() {
ArrayList<LatLngBean> arrayList = new ArrayList<LatLngBean>();
LatLngBean bean = new LatLngBean();
bean.setTitle("Ahmedabad");
bean.setSnippet("Hello,Ahmedabad");
bean.setLatitude("23.0300");
bean.setLongitude("72.5800");
arrayList.add(bean);
LatLngBean bean1 = new LatLngBean();
bean1.setTitle("Surat");
bean1.setSnippet("Hello,Surat");
bean1.setLatitude("21.1700");
bean1.setLongitude("72.8300");
arrayList.add(bean1);
LatLngBean bean2 = new LatLngBean();
bean2.setTitle("Vadodara");
bean2.setSnippet("Hello,Vadodara");
bean2.setLatitude("22.3000");
bean2.setLongitude("73.2000");
arrayList.add(bean2);
LoadingGoogleMap(arrayList);
}
/**
* @author Hasmukh Bhadani
* Set googleMap if require
*/
private void setUpMapIfNeeded() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
// Google Play Services are not available
if (status != ConnectionResult.SUCCESS) {
int requestCode = 10;
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
dialog.show();
} else if (googleMap == null) {
((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMapAsync((OnMapReadyCallback) this);
if (googleMap != null) {
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
}
}
}
/**
* @author Hasmukh Bhadani
* Loading Data to the GoogleMap
*/
// -------------------------Google Map
void LoadingGoogleMap(ArrayList<LatLngBean> arrayList) {
if (googleMap != null) {
googleMap.clear();
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
if (arrayList.size() > 0) {
try {
listLatLng = new ArrayList<LatLng>();
for (int i = 0; i < arrayList.size(); i++) {
LatLngBean bean = arrayList.get(i);
if (bean.getLatitude().length() > 0 && bean.getLongitude().length() > 0) {
double lat = Double.parseDouble(bean.getLatitude());
double lon = Double.parseDouble(bean.getLongitude());
Marker marker = googleMap.addMarker(new MarkerOptions()
.position(new LatLng(lat, lon))
.title(bean.getTitle())
.snippet(bean.getSnippet())
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
//Add Marker to Hashmap
hashMapMarker.put(marker, bean);
//Set Zoom Level of Map pin
LatLng object = new LatLng(lat, lon);
listLatLng.add(object);
}
}
SetZoomlevel(listLatLng);
} catch (NumberFormatException e) {
e.printStackTrace();
}
googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker position) {
LatLngBean bean = hashMapMarker.get(position);
Toast.makeText(getApplicationContext(), bean.getTitle(), Toast.LENGTH_SHORT).show();
}
});
}
} else {
Toast.makeText(getApplicationContext(), "Sorry! unable to create maps", Toast.LENGTH_SHORT).show();
}
}
/**
* @author Hasmukh Bhadani
* Set Zoom level all pin withing screen on GoogleMap
*/
public void SetZoomlevel(ArrayList<LatLng> listLatLng) {
if (listLatLng != null && listLatLng.size() == 1) {
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(listLatLng.get(0), 10));
} else if (listLatLng != null && listLatLng.size() > 1) {
final LatLngBounds.Builder builder = LatLngBounds.builder();
for (int i = 0; i < listLatLng.size(); i++) {
builder.include(listLatLng.get(i));
}
final ViewTreeObserver treeObserver = rlMapLayout.getViewTreeObserver();
treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
if (googleMap != null) {
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), findViewById(R.id.map)
.getWidth(), findViewById(R.id.map).getHeight(), 80));
rlMapLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
}
}
}
我的logcat在这里
FATAL EXCEPTION: main
Process: com.example.moses.ngongapp, PID: 28132
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.moses.ngongapp/com.example.moses.ngongapp.MapsActivity}: java.lang.ClassCastException: com.example.moses.ngongapp.MapsActivity cannot be cast to com.google.android.gms.maps.OnMapReadyCallback
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.access0(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5371)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:945)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:740)
Caused by: java.lang.ClassCastException: com.example.moses.ngongapp.MapsActivity cannot be cast to com.google.android.gms.maps.OnMapReadyCallback
at com.example.moses.ngongapp.MapsActivity.setUpMapIfNeeded(MapsActivity.java:90)
at com.example.moses.ngongapp.MapsActivity.onCreate(MapsActivity.java:44)
@Override
public void onMapReady(GoogleMap map) {
this.googleMap = map;
setUpMapIfNeeded();
setData()
}
在onMapReady()
中做地图相关的事情。
此处出错
((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMapAsync((OnMapReadyCallback) this);
错误清楚地写着“MapsActivity cannot be cast to com.google.android.gms.maps.OnMapReadyCallback
”。
所以,只需实现该接口
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
并从该接口实现相应的 onMapReady
方法。
那你就不用施法了。只是 getMapAsync(MapsActivity.this)
在该方法之内或之后之前,也不要执行任何 GoogleMap
相关功能。
关于您的评论,您必须跟踪您的代码以确切说明 if (googleMap != null) {
未被输入的原因。因为地图是空的 - 显然。但为什么?因为 getMapAsync
将 "wait" 直到地图准备就绪,此时 getMapAsync
在未来某个不确定的点被调用(因此异步,它在后台运行)。
换句话说,不要在onCreate中调用setUpMapIfNeeded或setData方法,而是仅在地图可用时调用(从参数到onMapReady方法)
@Override
public void onMapReady(GoogleMap map) {
this.googleMap = map;
setUpMapIfNeeded();
setData(); // this calls LoadingGoogleMap()
}
如果标记仍然不可见,请继续调试您的代码。该答案仅用于解决问题中提到的错误。
顺便说一句,your previous question was already implementing the interface
您可以实施 onMapReady 等新方法以及有关该方法的其余工作。
((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).
getMapAsync(new OnMapReadyCallback()
@Override
public void onMapReady(GoogleMap map) {
this.googleMap = map;
setUpMapIfNeeded();
setData()
});