Java android上谷歌地图的缩放事件
我们正在构建一个应用程序,该应用程序使用android的谷歌地图api 我有我的MapController和MapView,我使用以下方式启用内置的缩放控件:Java android上谷歌地图的缩放事件,java,android,events,google-maps,zooming,Java,Android,Events,Google Maps,Zooming,我们正在构建一个应用程序,该应用程序使用android的谷歌地图api 我有我的MapController和MapView,我使用以下方式启用内置的缩放控件: mapView.setBuiltInZoomControls(true); 我现在想得到一个事件,当用户实际缩放地图时,我该怎么做?我找不到这样的事件或任何可以检测到缩放级别变化的一般事件 更新 。文档建议使用mapView.SetBuilTinZoomControl(bool)。这没关系,但我根本不知道如何处理内置缩放控件中的事件。建
mapView.setBuiltInZoomControls(true);
我现在想得到一个事件,当用户实际缩放地图时,我该怎么做?我找不到这样的事件或任何可以检测到缩放级别变化的一般事件
更新
。文档建议使用mapView.SetBuilTinZoomControl(bool)。这没关系,但我根本不知道如何处理内置缩放控件中的事件。建议您使用带有setOnZoomInClickListener()的
要添加这些缩放控件,您需要:
ZoomControls mZoom = (ZoomControls) mapView.getZoomControls();
然后将mZoom添加到布局中。如操作所述,使用onUserInteractionEvent并自己进行测试。您可以使用
ZoomButtonsController zoomButton = mapView.getZoomButtonsController();
zoomButton.setOnZoomListener(listener);
希望对您有所帮助您可以像这样进行缩放控制
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="@+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="0l4sCTTyRmXTNo7k8DREHvEaLar2UmHGwnhZVHQ"
/>
<LinearLayout android:id="@+id/zoom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
这里我附上代码如何实现zoomcontrol
1> >XML文件应该是这样的
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="@+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="0l4sCTTyRmXTNo7k8DREHvEaLar2UmHGwnhZVHQ"
/>
<LinearLayout android:id="@+id/zoom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
这就是如何使用API的内置缩放控件
您可以有自己的自定义代码来实现放大和缩小,如下所示
public boolean onKeyDown(int keyCode, KeyEvent event)
{
MapController mc = mapView.getController();
switch (keyCode)
{
case KeyEvent.KEYCODE_3:
mc.zoomIn();
break;
case KeyEvent.KEYCODE_1:
mc.zoomOut();
break;
}
return super.onKeyDown(keyCode, event);
}
…我就是这样实施的
谢谢..Rakesh我使用这个库,它有一个onZoom函数侦听器。工作正常。您可以实现自己的缩放值基本“轮询”,以检测何时使用android更改了缩放 为可运行事件使用以下代码。这是您应该进行处理的地方
private Handler handler = new Handler();
public static final int zoomCheckingDelay = 500; // in ms
private Runnable zoomChecker = new Runnable()
{
public void run()
{
checkMapIcons();
handler.removeCallbacks(zoomChecker); // remove the old callback
handler.postDelayed(zoomChecker, zoomCheckingDelay); // register a new one
}
};
使用启动回调事件
protected void onResume()
{
super.onResume();
handler.postDelayed(zoomChecker, zoomCheckingDelay);
}
当您使用退出活动时,请停止
protected void onPause()
{
super.onPause();
handler.removeCallbacks(zoomChecker); // stop the map from updating
}
文章如果你想写更长的文章,可以找到这篇文章。我混合使用了上述内容。我发现使用timmer每半秒启动一个线程会导致地图变得非常简陋。可能是因为我每次都用了几个If语句。因此,我在onUserInteraction的500毫秒延迟后启动了线程。这为zoomLevel在线程开始运行之前提供了足够的时间进行更新,从而获得正确的zoomLevel,而无需每隔500毫秒运行一个线程
public void onUserInteraction() {
handler.postDelayed(zoomChecker, zoomCheckingDelay);
}
我想这个问题可能还有另一个答案。任何缩放后都会调用Overlay类draw方法,我相信这是在缩放级别更改后调用的。你不能设计你的应用程序来利用这一点吗?如果你想的话,你甚至可以使用一个虚拟覆盖来检测它。这不是比使用带有延迟的runnable更有效吗
@Override
public boolean draw (Canvas canvas, MapView mapView, boolean shadow, long when) {
int zoomLevel = mapView.getZoomLevel();
// do what you want with the zoom level
return super.draw(canvas, mapView, shadow, when);
}
这是一个干净的解决方案。只需将这个TouchOverlay私有类添加到您的活动和一个名为onZoom的方法(由这个内部类调用) 注意,您必须将此TouchOverlay添加到地图视图中,例如
mapView.getOverlays().add(new TouchOverlay());
每当用户触摸地图时,它都会跟踪缩放级别,例如双击或收缩缩放,然后在缩放级别更改时触发onZoom方法(使用缩放级别)
private class TouchOverlay extends com.google.android.maps.Overlay {
int lastZoomLevel = -1;
@Override
public boolean onTouchEvent(MotionEvent event, MapView mapview) {
if (event.getAction() == 1) {
if (lastZoomLevel == -1)
lastZoomLevel = mapView.getZoomLevel();
if (mapView.getZoomLevel() != lastZoomLevel) {
onZoom(mapView.getZoomLevel());
lastZoomLevel = mapView.getZoomLevel();
}
}
return false;
}
}
public void onZoom(int level) {
reloadMapData(); //act on zoom level change event here
}
使用Google Maps Android API v2,您可以使用类似的:
mMap.setOnCameraChangeListener(new OnCameraChangeListener() {
private float currentZoom = -1;
@Override
public void onCameraChange(CameraPosition pos) {
if (pos.zoom != currentZoom){
currentZoom = pos.zoom;
// do you action here
}
}
});
对于V2.0之前的版本,我创建了一个扩展MapView的类,该类在地图区域开始更改(onRegionBeginChange)和停止更改(onRegionEndChange)时向侦听器发出事件警报
谢谢你的回答。不推荐使用MapView.GetZoomControl(),建议使用MapView.SetBuilTinZoomControl(布尔)方法。但是我找不到任何地方可以从这些内置的缩放控件中获取任何事件。我明白了。看起来您可以使用一个未记录的mapView.getZoomButtonsController(),如中所述,否则您只需使用mapView.onkeydown并对缩放进行测试。我通过使用onUserInteraction事件和手动测试缩放级别的更改获得了想要的结果。如果有一条toast消息通知用户有必要放大以查看我的覆盖图,它的效果非常好。出于同样的目的,我尝试实现onUserInteraction事件,但仍然存在问题。我正在显示一个需要根据缩放级别进行缩放的图像,因此很明显,当用户缩放时,我想调用它的redraw()方法。我的问题是,当用户单击缩放按钮时,会调用onUserInteraction,因此zoomLevel尚未更新,只有在下一次交互(单击、跨距等)时,zoomLevel才会更新。因此,我的图像仅在实际缩放后的交互后更新。有什么想法吗?这个问题和答案是关于API v1的,我在下面添加了一个新的答案,说明在缩放级别更改之前调用了
onUserInteractionEvent()
。这实际上意味着,对于每个缩放事件,监控缩放的应用程序都会落后一个事件。@Paul:Hi。最初我没有考虑这个问题,但似乎你是对的,我所展示的敬酒永远是一个甚至落后。你可以创建一个<代码>汉德勒<代码>实例,并通过诸如<代码>延迟(新的Runnable)({…},500)< /代码>定期检查缩放级别的变化,但我真的不喜欢这种解决方案。我对这个答案给予了奖励,因为这是确定地图是否已被移动或缩放的最简单方法。这非常明确地回答了OP的问题,但只通过缩放按钮引发缩放事件。例如,Pinching不会调用侦听器的回调。听起来很有希望。我会仔细看看!使用您的解决方案,我能够轻松捕获缩放更改!ThxBrilliant解决方案,但是它没有检测到变焦的第一次变化。删除-1的第一个if语句修复了这一问题。setOnCameraChangeListener()
现在已被弃用
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
public class ExMapView extends MapView {
private static final String TAG = ExMapView.class.getSimpleName();
private static final int DURATION_DEFAULT = 700;
private OnRegionChangedListener onRegionChangedListener;
private GeoPoint previousMapCenter;
private int previousZoomLevel;
private int changeDuration; // This is the duration between when the user stops moving the map around and when the onRegionEndChange event fires.
private boolean isTouched = false;
private boolean regionChanging = false;
private Runnable onRegionEndChangeTask = new Runnable() {
public void run() {
regionChanging = false;
previousMapCenter = getMapCenter();
previousZoomLevel = getZoomLevel();
if (onRegionChangedListener != null) {
onRegionChangedListener.onRegionEndChange(ExMapView.this, previousMapCenter, previousZoomLevel);
}
}
};
public ExMapView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ExMapView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public ExMapView(Context context, String apiKey) {
super(context, apiKey);
init();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
isTouched = event.getAction() != MotionEvent.ACTION_UP;
return super.onTouchEvent(event);
}
@Override
public void computeScroll() {
super.computeScroll();
// If the map region is still changing (user is still scrolling or zooming), reset timer for onRegionEndChange.
if ((!isTouched && !getMapCenter().equals(previousMapCenter)) || (previousZoomLevel != getZoomLevel())) {
// If the region has just begun changing, fire off onRegionBeginChange event.
if (!regionChanging) {
regionChanging = true;
if (onRegionChangedListener != null) {
onRegionChangedListener.onRegionBeginChange(this, previousMapCenter, previousZoomLevel);
}
}
// Reset timer for onRegionEndChange.
removeCallbacks(onRegionEndChangeTask);
postDelayed(onRegionEndChangeTask, changeDuration);
}
}
private void init() {
changeDuration = DURATION_DEFAULT;
previousMapCenter = getMapCenter();
previousZoomLevel = getZoomLevel();
}
public void setOnRegionChangedListener(OnRegionChangedListener listener) {
onRegionChangedListener = listener;
}
public void setChangeDuration(int duration) {
changeDuration = duration;
}
public interface OnRegionChangedListener {
public abstract void onRegionBeginChange(ExMapView exMapView, GeoPoint geoPoint, int zoomLevel);
public abstract void onRegionEndChange(ExMapView exMapView, GeoPoint geoPoint, int zoomLevel);
}
}