【问题标题】:Creating OnDragListener for Google Map v2 Fragment为 Google Map v2 Fragment 创建 OnDragListener
【发布时间】:2013-06-17 20:54:58
【问题描述】:

我正在尝试为 google 地图片段设置 onDrag 侦听器,但无法触发拖动事件。由于地图不直接支持拖动事件,我正在尝试为视图实现拖动侦听器。我知道 onMarkerDrag 事件,但这对我没有好处,因为我不想移动标记。

捕获地图拖动事件的原因有两个:

首先检测用户是否平移了地图。如果他们没有,我喜欢将他们的位置保留在屏幕上,如果它不在地图上,则动画到他们的位置。如果他们已经平移了地图,我假设他们知道他们想看到什么并在屏幕上强制定位。 (这似乎应该包含在 API 中)

陷印的第二个原因是允许用户在地图上绘制线和多边形。我可以通过 onTap 事件(添加点)来做到这一点,但我也希望能够让他们徒手操作。

我的代码如下所示:

主活动:

    mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
    setUpMapIfNeeded();
    mMapView = findViewById(R.id.map);
    myMapDragListener = new MapDragListener();
    mMapView.setOnDragListener(myMapDragListener);

聆听者:

public class MapDragListener implements OnDragListener {
    /**
     * 
     */
    public MapDragListener() {
        super();
        say.logCat("MapDragListener: I'm ALIVE!!!!");
    }

    private AkamaiAnnounce say = new AkamaiAnnounce();
    private boolean inDrag;
    private boolean hasPanned=false;

    @Override
    public boolean onDrag(View v, DragEvent event) {
        say.logCat("MapDragListener.onDrag: " + event.toString());
        //String dotTAG = (String) getTag();
        if (event.getLocalState() != this) {
          return false;
        }
        boolean myResult = true;
        int action = event.getAction();
        float x = event.getX();
        float y = event.getY();
        switch (action) {
        case DragEvent.ACTION_DRAG_STARTED:
          inDrag = true;
          break;
        case DragEvent.ACTION_DRAG_LOCATION:
          break;
        case DragEvent.ACTION_DRAG_ENTERED:
          break;
        case DragEvent.ACTION_DRAG_EXITED:
          break;
        case DragEvent.ACTION_DROP:
          myResult = false;
          break;
        case DragEvent.ACTION_DRAG_ENDED:
          inDrag = false; // change color of original dot back
          hasPanned=true;
          break;
        default:
          myResult = false;
          break;
        }
        return false;
        //return myResult;

    }

    public boolean hasPanned() {
        return hasPanned;
    }

    public void setHasPanned(boolean hasPanned) {
        this.hasPanned = hasPanned;
    }

}

地图工作正常。侦听器实例化,但我的 onDrag 事件永远不会触发。有什么想法吗?

【问题讨论】:

  • 如果你在谈论拖动标记,v2 肯定有拖动监听器。使用implements OnMarkerDragListener
  • @tyczj 这不是拖动标记,而是平移整个地图。 Tim:这行不通,因为 map 会消耗事件。更新您的问题,说出您想要实现的目标,也许我们可以找到解决方案。

标签: android google-maps drag google-maps-android-api-2


【解决方案1】:

1) 创建包装类:

public class MapWrapperLayout extends FrameLayout {

    public interface OnDragListener {
        public void onDrag(MotionEvent motionEvent);
    }

    private OnDragListener mOnDragListener;

    public MapWrapperLayout(Context context) {
        super(context);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (mOnDragListener != null) {
            mOnDragListener.onDrag(ev);
        }
        return super.dispatchTouchEvent(ev);
    }

    public void setOnDragListener(OnDragListener mOnDragListener) {
        this.mOnDragListener = mOnDragListener;
    }
}

2) 创建 MapFragment 类的子类:

public class CustomMapFragment extends SupportMapFragment {

    private View mOriginalView;
    private MapWrapperLayout mMapWrapperLayout;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mOriginalView = super.onCreateView(inflater, container, savedInstanceState);

        mMapWrapperLayout = new MapWrapperLayout(getActivity());
        mMapWrapperLayout.addView(mOriginalView);

        return mMapWrapperLayout;
}

    @Override
    public View getView() {
        return mOriginalView;
    }

    public void setOnDragListener(MapWrapperLayout.OnDragListener onDragListener) {
        mMapWrapperLayout.setOnDragListener(onDragListener);
    }

3.1) 最后,在您的活动中:

    // Google map init block
    CustomMapFragment customMapFragment = ((CustomMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
    customMapFragment.setOnDragListener(new MapWrapperLayout.OnDragListener() {
        @Override
        public void onDrag(MotionEvent motionEvent) {
            Log.d("ON_DRAG", String.format("ME: %s", motionEvent));
            // Handle motion event:
        }
    });
    GoogleMap map = customMapFragment.getMap();

3.2) ... 在你的布局中:

<fragment android:id="@+id/map"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:name="your.package.CustomMapFragment"/>

【讨论】:

  • 请注意还有4636之类的问题。
  • @Aleh 我正在关注这个。我正在获取日志。我只想听 move 事件。如何仅获取此事件
  • @QadirHussain 如果我完全理解你的问题,那么:if(motionEvent.getAction()==MotionEvent.ACTION_MOVE){...}
【解决方案2】:

要获取包含 googleMap 的片段的拖动事件侦听器,可以使用以下 google 方法。我们可以得到地图的目标位置。

googleMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
          @Override
          public void onCameraIdle() {   
              Log.e(TAG,"==camera idle=="+ googleMap.getCameraPosition().target);

          }
      });
googleMap.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {
        @Override
        public void onCameraMoveStarted(int reason) {
            if (reason ==REASON_GESTURE) {
                isMaptouched=true;
                Toast.makeText(getActivity(), "The user gestured on the map.",
                        Toast.LENGTH_SHORT).show();
            } else if (reason ==REASON_API_ANIMATION) {
                Toast.makeText(getActivity(), "The user tapped something on the map.",
                        Toast.LENGTH_SHORT).show();
            } else if (reason ==REASON_DEVELOPER_ANIMATION) {
                Toast.makeText(getActivity(), "The app moved the camera.",
                        Toast.LENGTH_SHORT).show();
            }
        }


    });

【讨论】:

  • 最近几天在找这个.. :)
  • 谢谢,正在找这个。请注意,使用OnCameraMoveStartedListener.* 访问REASON_API_ANIMATIONREASON_DEVELOPER_ANIMATIONREASON_GESTURE 的值
  • 我更喜欢这个答案,干净,没有额外的黑客攻击
  • 谢谢!你的回答拯救了我的一天:)
【解决方案3】:

我使用 BehaviorSubject 做了类似的事情来判断地图是否脏(由用户移动)

    storeMap.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {
        @Override
        public void onCameraMoveStarted(int reason) {
            if (reason == REASON_GESTURE) {
                mapIsDirty.onNext(true);
            }
        }
    });
    storeMap.setOnCameraIdleListener(new OnCameraIdleListener() {
        @Override
        public void onCameraIdle() {
            if(mapIsDirty.getValue()) {
            // Do happy things
            mapIsDirty.onNext(false);
            }
        }
    });

【讨论】:

    【解决方案4】:

    我使用 onCameraMoveCancelledListener 解决了这个问题:

     mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                stopCamera=true;
            }
        });
    
    
        mMap.setOnCameraMoveCanceledListener(new GoogleMap.OnCameraMoveCanceledListener() {
            @Override
            public void onCameraMoveCanceled() {
                stopCamera = true;
            }
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 1970-01-01
      • 1970-01-01
      • 2013-01-24
      • 1970-01-01
      相关资源
      最近更新 更多