2016-08-12 119 views
10

我想實現一個在Google Map上自由繪圖的自定義模塊。談到實施時,我發現谷歌地圖onDrag()回調,並總是覆蓋我的自定義onDrag()函數。我不太確定如何使用我的FrameLayoutonDrag()覆蓋地圖點擊和拖動動作。在Google地圖上通過手指自由地繪圖

這是我的工作:

XML:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    tools:context=".MainActivity" > 

    <TextView 
     android:id="@+id/locinfo" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 


    <fragment 
     android:id="@+id/map" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     class="com.example.androidmapsv2.CustomMapFragment" > 
    </fragment> 

    <FrameLayout 
     android:id="@+id/fram_map" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" > 
    </FrameLayout> 

</LinearLayout> 

CustomMapFragment.java

package com.example.androidmapsv2; 

import com.google.android.gms.maps.MapFragment; 

import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

public class CustomMapFragment extends MapFragment { 
    public View mOriginalContentView; 
     public MapWrapperLayout mMapWrapperLayout; 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { 

      mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState); 
      mMapWrapperLayout = new MapWrapperLayout(getActivity()); 
      mMapWrapperLayout.addView(mOriginalContentView); 
      return mMapWrapperLayout; 
     } 

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

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

MapWrapperLayout.java

public class MapWrapperLayout extends FrameLayout { 
    private OnDragListener mOnDragListener; 

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

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

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

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

} 

MainActivity.java

package com.example.androidmapsv2; 

import java.util.ArrayList; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesUtil; 
import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.GoogleMap.OnMapClickListener; 
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener; 
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener; 
import com.google.android.gms.maps.OnMapReadyCallback; 
import com.google.android.gms.maps.Projection; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.Marker; 
import com.google.android.gms.maps.model.MarkerOptions; 
import com.google.android.gms.maps.model.Polygon; 
import com.google.android.gms.maps.model.PolygonOptions; 
import com.google.android.gms.maps.model.PolylineOptions; 

import android.app.Activity; 
import android.app.FragmentManager; 
import android.graphics.Color; 
import android.graphics.Point; 
import android.location.Location; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MotionEvent; 
import android.view.View; 
import android.widget.FrameLayout; 
import android.widget.TextView; 
import android.widget.Toast; 

public class MainActivity extends Activity 
    implements OnMapClickListener { 

    final int RQS_GooglePlayServices = 1; 
    private GoogleMap myMap; 

    Location myLocation; 
    TextView tvLocInfo; 
    ArrayList<LatLng> val = new ArrayList<LatLng>(); 
    boolean markerClicked; 
    PolygonOptions polygonOptions; 
    Polygon polygon; 
    FrameLayout fram_map; 
    CustomMapFragment myMapFragment ; 
    boolean Is_MAP_Moveable; 
    Projection projection; 
    public double latitude; 
    public double longitude; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     tvLocInfo = (TextView)findViewById(R.id.locinfo); 

     FragmentManager myFragmentManager = getFragmentManager(); 
     myMapFragment 
      = (CustomMapFragment)myFragmentManager.findFragmentById(R.id.map); 

     if (myMapFragment != null) { 

      myMapFragment.getMapAsync(new OnMapReadyCallback() { 
       @Override 
       public void onMapReady(GoogleMap map) { 
        loadMap(map); 
       } 
      }); 


      fram_map = (FrameLayout) findViewById(R.id.fram_map); 
      Is_MAP_Moveable = false; // to detect map is movable 



     } else { 
      Toast.makeText(this, "Error - Map Fragment was null!!", Toast.LENGTH_SHORT).show(); 

     } 


    } 

    public void Draw_Map() { 


     myMap.addPolyline(new PolylineOptions() 
       .addAll(val) 
       .color(Color.parseColor("#0971b2")).width(10f)); 

    } 


    protected void loadMap(GoogleMap map) { 
     // TODO Auto-generated method stub 
     myMap = map; 
     myMap.setMyLocationEnabled(true); 

     myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); 

     myMap.setOnMapClickListener(this); 
     //myMap.setOnMapLongClickListener(this); 
     //myMap.setOnMarkerClickListener(this); 

     markerClicked = false; 
     fram_map.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       float x = event.getX(); 
       float y = event.getY(); 

       int x_co = Math.round(x); 
       int y_co = Math.round(y); 

       projection = myMap.getProjection(); 
       Point x_y_points = new Point(x_co, y_co); 

       LatLng latLng = myMap.getProjection().fromScreenLocation(x_y_points); 
       latitude = latLng.latitude; 

       longitude = latLng.longitude; 

       switch (event.getAction()) { 
        case MotionEvent.ACTION_DOWN: 
         // finger touches the screen 
         val.add(new LatLng(latitude, longitude)); 

        case MotionEvent.ACTION_MOVE: 
         // finger moves on the screen 
         val.add(new LatLng(latitude, longitude)); 

        case MotionEvent.ACTION_UP: 
         v.performClick(); 

         // finger leaves the screen 
         Draw_Map(); 
         break; 
       } 

       if (Is_MAP_Moveable == true) { 
        return true; 

       } else { 
        return false; 
       } 
      } 
     }); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.activity_main, menu); 
     return true; 
    } 


    @Override 
    protected void onResume() { 

     super.onResume(); 

     int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext()); 

     if (resultCode == ConnectionResult.SUCCESS){ 
      Toast.makeText(getApplicationContext(), 
        "isGooglePlayServicesAvailable SUCCESS", 
        Toast.LENGTH_LONG).show(); 
     }else{ 
      GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices); 
     } 

    } 

    @Override 
    public void onMapClick(LatLng point) { 

     Is_MAP_Moveable = !Is_MAP_Moveable; 
     Toast.makeText(getApplicationContext(), 
       Is_MAP_Moveable ? "drawing activated" : "drawing disabled", 
       Toast.LENGTH_SHORT).show(); 
//  tvLocInfo.setText(point.toString()); 
//  myMap.animateCamera(CameraUpdateFactory.newLatLng(point)); 
//  
//  markerClicked = false; 
    } 

// @Override 
// public void onMapLongClick(LatLng point) { 
//  tvLocInfo.setText("New marker [email protected]" + point.toString()); 
//  myMap.addMarker(new MarkerOptions().position(point).title(point.toString())); 
//  
//  markerClicked = false; 
// } 
// 
// @Override 
// public boolean onMarkerClick(Marker marker) { 
//  
//  if(markerClicked){ 
//   
//   if(polygon != null){ 
//    polygon.remove(); 
//    polygon = null; 
//   } 
//   
//   polygonOptions.add(marker.getPosition()); 
//   polygonOptions.strokeColor(Color.RED); 
//   polygonOptions.fillColor(Color.BLUE); 
//   polygon = myMap.addPolygon(polygonOptions); 
//  }else{ 
//   if(polygon != null){ 
//    polygon.remove(); 
//    polygon = null; 
//   } 
//   
//   polygonOptions = new PolygonOptions().add(marker.getPosition()); 
//   markerClicked = true; 
//  } 
//  
//  return true; 
// } 

} 

回答

2

一種方法可以創建一個View在你的地圖,這個View創建OnTouchListener攔截地圖亮點:

activity_maps.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent"> 

    <fragment 
     android:id="@+id/map" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:name="com.google.android.gms.maps.SupportMapFragment" /> 

    <View 
     android:id="@+id/draggable" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:clickable="true" /> 

</RelativeLayout> 

MapsActivity.java

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback { 
    private GoogleMap mMap; 
    private View draggableView; 
    private List<LatLng> polylinePoints = new ArrayList<>(); 
    private Polyline polyline; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_maps); 

     SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
       .findFragmentById(R.id.map); 
     mapFragment.getMapAsync(this); 

     draggableView = findViewById(R.id.draggable); 
    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) { 
     mMap = googleMap; 

     draggableView.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View view, MotionEvent motionEvent) { 
       LatLng position = mMap.getProjection().fromScreenLocation(
         new Point((int) motionEvent.getX(), (int) motionEvent.getY())); 

       if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 
        if (polyline != null) { 
         polyline.remove(); 
         polyline = null; 
        } 
        polyline = mMap.addPolyline(
          new PolylineOptions().color(Color.RED).addAll(polylinePoints)); 
       } else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE){ 
        polylinePoints.add(position); 
        polyline.setPoints(polylinePoints); 
       } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) { 
        // Close the polyline? 
       } 
       return true; 
      } 
     }); 
    } 
} 
相關問題