当前位置: 动力学知识库 > 问答 > 编程问答 >

java - Drawing freely by fingers on Google Map

问题描述:

I want to implement a custom module for free drawing on Google Map. When it comes to the implementation, I have found that the Google Map onDrag() callback and always overrides my custom onDrag() function. I am not so sure how to use my FrameLayout onDrag() to override the map click and drag motion.

Here is my working:

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;

// }

}

网友答案:

One way can be to create a View over your map and create an OnTouchListener for this View to intercept map touches:

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;
            }
        });
    }
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: