如何使用ClickListener在Android Studio中启动标记位置?

时间:2016-05-26 04:11:50

标签: java android google-maps onclicklistener google-maps-api-2

此应用程序旨在从2个坐标点获得距离。方法是单击要计算距离的位置地图的地图。但是从一开始就存在问题,即应用程序无法改变位置。

这是我的代码:

public class MapsActivity extends FragmentActivity {

// the Google Map object
private GoogleMap mMap;
//ArrayList markerPoints;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // we set the layout for the Activity
    setContentView(R.layout.activity_maps);

    // the geocoder is instantiated for the first time
    geocoder=new Geocoder(this);

    // if there isn't a map, it will be created
    setUpMapIfNeeded();
}


// LatLng objects store a pair of terrestrial coordinates (latitude and longitude)
private static LatLng STARTING_MARKER_POSITION =new LatLng(3.099465, 101.717111);

/* distanceFrom indicates the starting point to calculate the distance from.
   It's initialized with STARTING_MARKER_POSITION
*/

private LatLng distanceFrom= STARTING_MARKER_POSITION;

// line will be drawn at the click event
private Polyline line=null;

// A Geocoder can transform a pair of latitude/longitude into a street address and viceversa.
// We'll use it in the listener
private static Geocoder geocoder=null;


private GoogleMap.OnMapClickListener clickListener=new GoogleMap.OnMapClickListener() {
    @Override
    public void onMapClick(final LatLng pos) {

        // this method is called when the user taps the map

        // if a line already appears, it's removed
        if (line!=null)
            line.remove();

        // a new line is created
        line = mMap.addPolyline(new PolylineOptions()
                .add(distanceFrom, pos)
                .width(9) // width of the line
                .color(Color.BLUE)); // line color

        // call the converter object for geocoding invocation and distance calculation
        new AddressConverter().execute(distanceFrom, pos);

    }
};


@Override
protected void onResume() {
    super.onResume();

    // the availability of the GoogleMap will be checked before the Activity starts interacting with the user
    setUpMapIfNeeded();
}

private void setUpMapIfNeeded() {

    // the map is created only it has not been initialized
    if (mMap == null) {

        // the map is located in the layout
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

        // if a map exists, we proceed with initialization
        if (mMap != null) {
            setUpMap();
        }
    }
}

// Now it's time to configure the map. We can add markers, shapes, event handlers and so on
private void setUpMap() {

    // the camera will be positioned according to the new coordinates
    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(STARTING_MARKER_POSITION, 14));




    // we choose the type of the map: Satellite in this case
    mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

    // markerOptions describes the marker we want to place
    MarkerOptions markerOptions=new MarkerOptions()
            .position(STARTING_MARKER_POSITION)
            .draggable(true);

    // the marker has to be draggable as we'll move it

    // the marker is rendered on the map
    mMap.addMarker(markerOptions);

    // we define the object to invoke when the marker is dragged
    mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener()
    {
        @Override
        public void onMarkerDragStart(Marker arg0)
        {
            // this method is called when the drag starts
            // the operation we need is the cancellation of a preexisting line
            if (line!=null)
                line.remove();
        }
        @Override
        public void onMarkerDragEnd(final Marker pos)
        {
            // we get the final position of the marker
            distanceFrom=pos.getPosition();

        }

        @Override
        public void onMarkerDrag(Marker arg0)
        {
            // operations performed during the movement. Nothing to do
        }
    });

    // the callback to invoke is set
    mMap.setOnMapClickListener(clickListener);
}

// we want to know which address corresponds to this location
// we use AsyncTask to perform slower operations on a separate thread
private class AddressConverter extends AsyncTask<LatLng,Void,String>
{
    // The ProgressDialog window we'll show during the calculation
    private ProgressDialog progress=null;

    // this method is called before the background job starts. It works on the main thread
    @Override
    protected void onPreExecute() {

        // ProgressDialog is shown
        progress= ProgressDialog.show(MapsActivity.this,"Distance calculator","We are calcultating the distance...", true,false);
    }

    // this method works on a separate thread
    // it performs geocoding operations to retrieve the address of the points and calculates the distance in meters between them
    @Override
    protected String doInBackground(LatLng... params) {

        float[] distance=new float[1];
        try {
            // the Location class contains what we need to calculate distances

            Location.distanceBetween(params[0].latitude,params[0].longitude,params[1].latitude,params[1].longitude,distance);

            // geocoding operations
            List<Address> fromResult=geocoder.getFromLocation(params[0].latitude,params[0].longitude,1);
            List<Address> toResult=geocoder.getFromLocation(params[1].latitude,params[1].longitude,1);

            // the message informs the user about the distance from the marker to the point selected with the click
            // if we have got both the addresses, we use them to compose the message, otherwise we show only the distance
            if (fromResult.size()>0 && toResult.size()>0)
            {
              //  ((TextView) findViewById(R.id.tvDuration)).setText(route.duration.text);
                 return "The distance between " + getAddressDescription(fromResult.get(0)) + " and " + getAddressDescription(toResult.get(0)) + " is " + Math.round(distance[0]) + " meters";
            }
            else
                return "The distance is " + Math.round(distance[0]) + " meters";

        }
        catch (IOException e) {
            return "The distance is " + Math.round(distance[0]) + " meters";
        }
    }

    @Override
    protected void onPostExecute(String message)
    {
        if (progress!=null)
            progress.dismiss();

        // The builder of the window is instantiated
        AlertDialog.Builder builder=new AlertDialog.Builder(MapsActivity.this);
        builder.setTitle("Distance");
        builder.setMessage(message);

        // the Alert dialog appears
        builder.show();
    }



}

// this method only formats the message with addresses
private String getAddressDescription(Address a)
{
    String city=a.getLocality();
    String address=a.getAddressLine(0);

    return "'"+address+"' ("+city+")";

}}

1 个答案:

答案 0 :(得分:2)

使用 distanceBetween()方法,它会以米为单位给出精确的距离。

Location.distanceBetween(double startLatitude, double startLongitude,
double endLatitude, double endLongitude, float[] results);