Lee*_*Lee 94 android android-mapview google-maps-android-api-2
我正在使用新的Android Google Maps API.
我创建了一个包含MapFragment的活动.在活动中,onResume我将标记设置为GoogleMap对象,然后为地图定义包含所有标记的边界框.
这是使用以下伪代码:
LatLngBounds.Builder builder = new LatLngBounds.Builder();
while(data) {
LatLng latlng = getPosition();
builder.include(latlng);
}
CameraUpdate cameraUpdate = CameraUpdateFactory
.newLatLngBounds(builder.build(), 10);
map.moveCamera(cameraUpdate);
Run Code Online (Sandbox Code Playgroud)
调用map.moveCamera()导致我的应用程序崩溃与以下堆栈:
Caused by: java.lang.IllegalStateException:
Map size should not be 0. Most likely, layout has not yet
at maps.am.r.b(Unknown Source)
at maps.y.q.a(Unknown Source)
at maps.y.au.a(Unknown Source)
at maps.y.ae.moveCamera(Unknown Source)
at com.google.android.gms.maps.internal.IGoogleMapDelegate$Stub
.onTransact(IGoogleMapDelegate.java:83)
at android.os.Binder.transact(Binder.java:310)
at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a
.moveCamera(Unknown Source)
at com.google.android.gms.maps.GoogleMap.moveCamera(Unknown Source)
at ShowMapActivity.drawMapMarkers(ShowMapActivity.java:91)
at ShowMapActivity.onResume(ShowMapActivity.java:58)
at android.app.Instrumentation
.callActivityOnResume(Instrumentation.java:1185)
at android.app.Activity.performResume(Activity.java:5182)
at android.app.ActivityThread
.performResumeActivity(ActivityThread.java:2732)
Run Code Online (Sandbox Code Playgroud)
如果 - 而不是newLatLngBounds()工厂方法我使用newLatLngZoom()方法,那么不会发生相同的陷阱.
是将onResume标记绘制到GoogleMap对象上的最佳位置,还是应该绘制标记并将摄像机位置设置在其他位置?
Pau*_*kov 133
您可以在OnCameraChangeListener中使用简单的newLatLngBounds方法.一切都将完美运行,您不需要计算屏幕尺寸.此事件发生在地图大小计算后(据我所知).
例:
map.setOnCameraChangeListener(new OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition arg0) {
// Move camera.
map.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 10));
// Remove listener to prevent position reset on camera move.
map.setOnCameraChangeListener(null);
}
});
Run Code Online (Sandbox Code Playgroud)
小智 56
那些答案很好,但我会采用不同的方法,更简单的方法.如果该方法仅在布局后布局,则只需等待它:
map.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 30));
}
});
Run Code Online (Sandbox Code Playgroud)
Lee*_*Lee 50
好的,我把它解决了.如此处所述,API不能在预布局之前使用.
要使用的正确API描述为:
注意:如果要在地图经过布局后用于移动相机,则仅使用更简单的方法newLatLngBounds(boundary,padding)生成CameraUpdate.在布局期间,API会计算正确投影边界框所需的地图显示边界.相比较而言,可以使用通过在任何时间更复杂的方法newLatLngBounds(边界,宽度,高度,填充)返回的CameraUpdate,甚至在地图已布局发生了,因为API从您传递参数计算显示边界.
为了解决这个问题,我计算了我的屏幕尺寸并提供了宽度和高度
public static CameraUpdate newLatLngBounds(
LatLngBounds bounds, int width, int height, int padding)
Run Code Online (Sandbox Code Playgroud)
然后,这允许我指定边界框预布局.
Dan*_*ato 34
解决方案比那简单....
// Pan to see all markers in view.
try {
this.gmap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
} catch (IllegalStateException e) {
// layout not yet initialized
final View mapView = getFragmentManager()
.findFragmentById(R.id.map).getView();
if (mapView.getViewTreeObserver().isAlive()) {
mapView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
// We check which build version we are using.
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
mapView.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
} else {
mapView.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
}
gmap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
IllegalStateException而是在视图上捕获并使用全局侦听器.使用其他方法预先设置边界大小(预布局)意味着您必须计算THE VIEW的大小,而不是屏幕设备.如果您使用地图全屏显示并且不使用片段,则它们仅匹配.
小智 15
这是我的修复,只是等待,直到在这种情况下加载地图.
final int padding = getResources().getDimensionPixelSize(R.dimen.spacing);
try {
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(pCameraBounds, padding));
} catch (IllegalStateException ise) {
mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(pCameraBounds, padding));
}
});
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*enT 14
添加和删除标记可以在布局完成之前完成,但移动相机不能(除了使用newLatLngBounds(boundary, padding)OP的答案中所述).
可能执行初始相机更新的最佳场所是使用一次性OnGlobalLayoutListener如图谷歌的示例代码,例如,见下面摘自setUpMap()于MarkerDemoActivity.java:
// Pan to see all markers in view.
// Cannot zoom to bounds until the map has a size.
final View mapView = getSupportFragmentManager()
.findFragmentById(R.id.map).getView();
if (mapView.getViewTreeObserver().isAlive()) {
mapView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@SuppressLint("NewApi") // We check which build version we are using.
@Override
public void onGlobalLayout() {
LatLngBounds bounds = new LatLngBounds.Builder()
.include(PERTH)
.include(SYDNEY)
.include(ADELAIDE)
.include(BRISBANE)
.include(MELBOURNE)
.build();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
}
});
}
Run Code Online (Sandbox Code Playgroud)
Teo*_*nke 12
接受的答案对我不起作用,因为我必须在我的应用程序的不同位置使用相同的代码.
我没有等待相机改变,而是根据Lee建议的指定地图大小创建了一个简单的解决方案.这是为了您的地图是屏幕的大小.
// Gets screen size
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
// Calls moveCamera passing screen size as parameters
map.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), width, height, 10));
Run Code Online (Sandbox Code Playgroud)
希望它可以帮助别人!
正如评论中指出的那样,接受的答案是有点hacky.实施后,我注意到IllegalStateException分析中有大量可接受的日志.我所使用的溶液是添加OnMapLoadedCallback在其中CameraUpdate被执行.回调被添加到GoogleMap.地图完全加载后,将执行相机更新.
这会导致地图在执行相机更新之前简要显示缩小(0,0)视图.我觉得这比造成崩溃或依赖无证件行为更容易接受.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(bounds.getCenter(),10));
Run Code Online (Sandbox Code Playgroud)
用这个它对我来说很有用