animateCamera工作并移动摄影机';t代表谷歌地图-Android
我需要移动摄像机以覆盖上面的所有标记。因此,我构建animateCamera工作并移动摄影机';t代表谷歌地图-Android,android,google-maps,illegalstateexception,Android,Google Maps,Illegalstateexception,我需要移动摄像机以覆盖上面的所有标记。因此,我构建LatLngBounds,然后尝试调用mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(LatLngBounds,15))。问题是,当我使用moveCamera()方法时,我得到了IllegalStateException,但当我使用animateCamera()时,它运行得很好。我在onMapReadycallback中调用这两个方法。发生了什么事 我的stacktrace(主要部分): 一
LatLngBounds
,然后尝试调用mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(LatLngBounds,15))
。问题是,当我使用moveCamera()
方法时,我得到了IllegalStateException
,但当我使用animateCamera()
时,它运行得很好。我在onMapReady
callback中调用这两个方法。发生了什么事
我的stacktrace(主要部分):
一种方法知道地图大小而另一种不知道,这怎么可能呢?根据,在地图经过布局之前,不能使用此API。上面说
注意:仅使用更简单的方法newLatLngBounds(边界、填充)
如果要用于移动相机,则生成相机更新
相机在地图经过布局之后。在布局期间,API
计算需要显示的地图显示边界
正确投影边界框。相比之下,您可以使用
由更复杂的方法返回的CameraUpdate
随时更新边界(边界、宽度、高度、填充),甚至
在地图经过布局之前,因为API计算
显示传递的参数的边界
但是您可以使用onCamerachenglistener
中的newLatLngBounds()
方法。一切都将完美运行,您不需要计算屏幕大小。据我所知,此事件发生在地图大小计算之后
mMap.setOnCameraChangeListener(new OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition arg0) {
// Move camera.
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 15));
// Remove listener to prevent position reset on camera move.
mMap.setOnCameraChangeListener(null);
}
});
自从Google Maps SDK更新到最新版本后,它就被弃用了。我也遇到过这个问题,我发现它也有类似的作用。到目前为止,我看到它的回调方法
onCameraIdle
总是在onMapReady
之后调用。因此,我的方法看起来像Google Maps SDK 9.6+的这段代码(考虑到它放在活动中):
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set content view and call getMapAsync() on MapFragment
}
@Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
map.setOnCameraIdleListener(this);
// other initialization stuff
}
@Override
public void onCameraIdle() {
/*
Here camera is ready and you can operate with it.
you can use 2 approaches here:
1. Update the map with data you need to display and then set
map.setOnCameraIdleListener(null) to ensure that further events
will not call unnecessary callback again.
2. Use local boolean variable which indicates that content on map
should be updated
*/
}
正如这里清楚记录的那样
请注意,OnMapReadyCallback并不保证地图已经过布局。因此,调用回调方法时可能尚未确定映射的大小。如果需要知道维度或调用API中需要知道维度的方法,请获取地图的视图并注册ViewTreeObserver.OnGlobalLayoutListener
不要链接OnMapReadyCallback和OnGlobalLayoutListener侦听器,而是独立地注册和等待这两个回调,因为回调可以以任何顺序触发
因此,您必须使用这两个(onMapReady、onGlobalLayout)回调来确保映射已完全加载,并且大小已确定
private GoogleMap mMap;
private boolean isMapLoaded;
SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mapFragment.getView().getViewTreeObserver().addOnGlobalLayoutListener(this);
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (!isMapLoaded) {
isMapLoaded = true;
return;
}
initMap();
}
@Override
public void onGlobalLayout() {
if (!isMapLoaded) {
isMapLoaded = true;
return;
}
initMap();
}
private void initMap() {
//maps fully loaded instance with defined size will be available here.
//mMap.animateCamera();
//mMap.moveCamera();
}
多亏了@Viacheslav,我在SetonCameraideListener
中也做到了这一点:
override fun onMapReady(googleMap: GoogleMap?) {
this.googleMap = googleMap
// setupMap()
googleMap?.setOnCameraIdleListener {
// Remove the listener to stop calling the same event.
googleMap.setOnCameraIdleListener(null)
// Now you can use 'moveCamera'.
// I also added a delay of 100 ms here in order to draw the map
// and correctly calculate distances. If this is your case, then add a short pause.
val position = LatLng(latitude, longitude)
val camera = CameraUpdateFactory.newLatLngZoom(position, 10)
// Strange, but it doesn't work for
// val camera = CameraUpdateFactory.zoomTo(10)
googleMap.moveCamera(camera)
// If you later want to listen to camera movements (start-stop),
// you should change setOnCameraIdleListener here.
googleMap.setOnCameraIdleListener{
// A listener for future camera stops.
...
}
}
}
setOnCameraideListener
是移动相机和计算距离的合适侦听器。您也可以在onMapReady
中获得相同的延迟(100-300毫秒)。您能解释一下为什么animateCamera可以工作而moveCamera不能工作吗?我最后做的就是这个。作品perfectly@Justin如果没有任何代码示例,很难说为什么。从我的角度来看,我可以确认它在最新的MapsAPI上运行良好。您的示例非常有价值,但是如果布局是在地图准备好之前布局的,您如何在OnGlobalYout()
中执行initMap()
?如果我错了,很抱歉,但是我相信这应该有一个if(mMap!=null)
在onGlobalLayout
之前检查initMap()
只是一个预防措施,删除setOnMapLoadedCallback()
如果使用了它,如果您将它与建议的配置一起使用,它将进入一个循环谢谢您的提示。我尝试了你的代码,添加了removeOnGlobalLayoutListener
()。在我的例子中,onGlobalLayout
是在onMapReady
之前调用的。请参阅@Viacheslav的答案,setsetonCameraideListener
(使用后清除)。
override fun onMapReady(googleMap: GoogleMap?) {
this.googleMap = googleMap
// setupMap()
googleMap?.setOnCameraIdleListener {
// Remove the listener to stop calling the same event.
googleMap.setOnCameraIdleListener(null)
// Now you can use 'moveCamera'.
// I also added a delay of 100 ms here in order to draw the map
// and correctly calculate distances. If this is your case, then add a short pause.
val position = LatLng(latitude, longitude)
val camera = CameraUpdateFactory.newLatLngZoom(position, 10)
// Strange, but it doesn't work for
// val camera = CameraUpdateFactory.zoomTo(10)
googleMap.moveCamera(camera)
// If you later want to listen to camera movements (start-stop),
// you should change setOnCameraIdleListener here.
googleMap.setOnCameraIdleListener{
// A listener for future camera stops.
...
}
}
}