Java – draw freely on Google maps with your finger

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
分享
二维码
< <上一篇
下一篇>>