Java – draw freely on Google maps with your finger
•
Java
I want to implement a custom module for free drawing on Google maps When it comes to implementation, I find that Google map ondrag() callback always overrides my custom ondrag() function I'm not sure how to use my FrameLayout ondrag() to overlay the map click and drag action
This is my job:
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 added@" + 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; // } }
Solution
One way is to create a view through the map and create an ontouchlistener for this view to intercept map touch:
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; } }); } }
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
二维码