2013-06-20 45 views
8

Tôi đang cố gắng thiết lập Trình xử lý bản đồ trên cho một đoạn bản đồ google nhưng không thể kéo sự kiện kéo vào. Vì bản đồ không hỗ trợ trực tiếp sự kiện kéo, tôi đang cố gắng triển khai trình xử lý kéo cho Chế độ xem. Tôi biết về sự kiện onMarkerDrag, nhưng điều đó làm tôi không tốt vì tôi không cố di chuyển các điểm đánh dấu xung quanh.Tạo OnDragListener cho Google Map v2 Fragment

Lý do bẫy sự kiện kéo bản đồ là gấp đôi:

Đầu tiên phát hiện xem người dùng có quét bản đồ hay không. Nếu họ không có, tôi muốn giữ vị trí của họ trên màn hình, và animate đến vị trí của họ nếu nó không có trên bản đồ. Nếu họ đã rà soát bản đồ, tôi cho rằng họ biết những gì họ muốn xem và ép buộc vị trí trên màn hình. (điều này có vẻ giống như một cái gì đó nên được bao gồm trong API)

Lý do thứ hai cho việc bẫy là cho phép người dùng vẽ đường kẻ và đa giác trên bản đồ. Tôi có thể làm điều này với các sự kiện onTap (thêm điểm), nhưng tôi muốn có thể cho phép họ tự do nó.

Mã của tôi trông như thế này:

MainActivity:

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

The Listener:

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; 
    } 

} 

bản đồ này hoạt động tốt. Người nghe ngay lập tức, nhưng sự kiện onDrag của tôi không bao giờ cháy. Bất kỳ ý tưởng?

+0

nếu bạn đang nói về các dấu hiệu kéo, chắc chắn V2 không có người nghe kéo. sử dụng 'thực hiện 'OnMarkerDragListener' – tyczj

+1

@tyczj Nó không phải là về việc kéo các điểm đánh dấu, mà còn xoay quanh toàn bộ bản đồ. Tim: Điều này sẽ không hoạt động vì bản đồ tiêu thụ các sự kiện. Cập nhật câu hỏi của bạn, nói những gì bạn muốn đạt được và có thể chúng tôi có thể tìm ra giải pháp. –

Trả lời

18

1) Tạo lớp wrapper:

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) Tạo lớp con của lớp 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) Cuối cùng, trong hoạt động của bạn:

// 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). .. và trong bố cục của bạn:

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

Hãy nhớ rằng vẫn còn có những vấn đề như [4636] (https://code.google.com/p/gmaps-api-issues/issues/detail?id=4636). – JJD

+0

@Aleh Im theo dõi điều này. Tôi đang lấy Nhật ký. Tôi chỉ muốn nghe sự kiện di chuyển. làm thế nào để có được sự kiện này chỉ –

+1

@ QadirHussain Nếu tôi hiểu chính xác câu hỏi của bạn, thì: if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {...} – Aleh

4

Để nhận trình xử lý sự kiện kéo một đoạn có chứa googleMap, người ta có thể sử dụng phương thức dưới đây của google. Chúng tôi có thể có được vị trí mục tiêu của bản đồ.

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(); 
      } 
     } 


    }); 
+1

tìm kiếm điều này từ vài ngày qua .. :) –

0

tôi đã làm một cái gì đó giống như tương tự sử dụng một BehaviorSubject để biết bản đồ là bẩn (di chuyển bằng cách sử dụng)

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); 
      } 
     } 
    }); 
Các vấn đề liên quan