web-dev-qa-db-fra.com

Android: faites glisser la carte tout en gardant le marqueur au centre

J'obtiens actuellement l'emplacement actuel de l'appareil (lat, lng) dans MapActivity. Maintenant, je veux laisser l'utilisateur déplacer la carte, tout en gardant le marqueur au centre. Cela signifie que chaque fois que la carte est déplacée, l'emplacement actuel sera mis à jour. (Droite?)

J'ai suivi ceci Comment déplacer une carte sous un marqueur? et Comment attacher un marqueur flexible sur une carte quelque chose comme Uber et Lyft? mais je n'ai pas pu clarifier mon concept.

Activity_map.xml (ici j'ai ajouté ImageView)

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

<fragment
    Android:id="@+id/map"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    class="com.google.Android.gms.maps.MapFragment"
    />

<ImageView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_centerInParent="true"
    Android:src="@drawable/gps"
    />

 </RelativeLayout>

Ma MapActivity est la suivante:

 public class MapActivity extends FragmentActivity implements      OnMapReadyCallback,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener,GoogleMap.OnInfoWindowClickListener{

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_map);
   // int x =_st.jsonArray.length();
    if (Android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        checkLocationPermission();
    }

    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    fragmentOnMap = (FragmentOnMap)getFragmentManager().findFragmentById(R.id.fragment_bottom);
    getFragmentManager().beginTransaction().hide(fragmentOnMap);

}

@Override
public void onMapReady(GoogleMap googleMap) {


    //Get Last Known Location and convert into Current Longitute and Latitude
    final LocationManager mlocManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    final Location currentGeoLocation = mlocManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

    double currentLat = currentGeoLocation.getLatitude();
   double currentLon = currentGeoLocation.getLongitude();

    LatLng currentLatLng = new LatLng(currentLat,currentLon);
    //Toast.makeText(this,"Cur Lat" +currentLat+"Lon"+currentLon,Toast.LENGTH_LONG).show();

    // Get JSON String and Break it down into individual nodes
    //double x=_location.getLatitude();
    //double y=_location.getLongitude();
    json_string = getIntent().getExtras().getString("JSON_DTA");
    LatLng latLng = null;
    try {
        int count = 0;
        //jsonObject = new JSONObject(json_string);
        jsonArray = new JSONArray(json_string);

        while (count < jsonArray.length()) {
            JSONObject JO = jsonArray.getJSONObject(count);
            _id = JO.getInt("id");
            _doctorname = JO.getString("doctorname");
            _doclat = JO.getString("latitude");
            _doclong = JO.getString("longitude");

            count++;

            Double d = Double.parseDouble(_doclat);
            Double e = Double.parseDouble(_doclong);
            latLng = new LatLng(d, e);

            DecimalFormat df = new DecimalFormat("####0.0");

            DistanceBetweenPoints distanceBetweenPoints = new DistanceBetweenPoints();
            double  distance = distanceBetweenPoints.CalculationByDistance(currentLatLng,latLng);

            double distanceThreshHold = 7 ;
            if(distance < distanceThreshHold  )
            {
                mMap = googleMap;
                mMap.setOnInfoWindowClickListener(this);
                MarkerOptions _markeroptions = new MarkerOptions()
                        .position(latLng)
                        .title(_doctorname+":  " + df.format(distance) + " KM" )
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.smallest_logo));
                mMap.addMarker(_markeroptions);

                mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);


            }
            else
            {
                mMap = googleMap;
            }

     }


    } catch (JSONException e) {
        e.printStackTrace();
    }

    //Initialize Google Play Services
    if (Android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            buildGoogleApiClient();

            mMap.setMyLocationEnabled(true);

        }
    } else {
        buildGoogleApiClient();
        mMap.setMyLocationEnabled(true);
    }
}

protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();
}
@Override
public void onConnected(@Nullable Bundle bundle) {

    mLocationRequest = new LocationRequest();

    mLocationRequest.setInterval(1000);
    mLocationRequest.setFastestInterval(1000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

}

@Override
public void onConnectionSuspended(int i) {

}


@Override
public void onLocationChanged(Location location) {

        mLastLocation = location;
        if (mCurrLocationMarker != null) {
            mCurrLocationMarker.remove();
        }


        //Place current location marker
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.title("Current Position");
        markerOptions.draggable(true);

        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_Magenta));
        mCurrLocationMarker = mMap.addMarker(markerOptions);


      //  Toast.makeText(this, "Current" + latLng, Toast.LENGTH_LONG).show();
        String tag = null;
        Log.d(tag, "lon: " + location.getLongitude() + " ----- lat: " + location.getLatitude());


        //move map camera
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(11));


        //stop location updates
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }


    }




@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

public boolean checkLocationPermission(){
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        // Asking user if explanation is needed
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

            //Prompt the user once explanation has been shown
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);


        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);
        }
        return false;
    } else {
        return true;
    }
}
@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // Permission was granted.
                if (ContextCompat.checkSelfPermission(this,
                        Manifest.permission.ACCESS_FINE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED) {

                    if (mGoogleApiClient == null) {
                        buildGoogleApiClient();
                    }
                    mMap.setMyLocationEnabled(true);
                }

            } else {

                // Permission denied, Disable the functionality that depends on this permission.
                Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
            }
            return;
        }

        // other 'case' lines to check for other permissions this app might  request.
        //You can add here other case statements according to your requirement.
    }
}

Votre aide sera très appréciée. Je vous remercie.

11
AIS

Avoir une carte sous une ImageView avec votre icône de marqueur serait la meilleure façon d'aller ici (juste un framelayout avec votre fragment de carte sous et votre image de marqueur centrée en haut devrait fonctionner). Ensuite, vous pouvez utiliser un OnCameraIdleListener qui recevra un rappel lorsque le mouvement de la carte sera terminé. Il suffit donc de définir une instance de OnCameraIdleListener sur votre carte pour écouter les rappels de mouvement comme ceci:

map.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
        @Override
        public void onCameraIdle() {
            //get latlng at the center by calling
            LatLng midLatLng = map.getCameraPosition().target;
        }
    });
31
Joey Dalu

Essayez d'abord cette disposition pour votre Activity_map.xml:

<RelativeLayout
    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"
        class="com.google.Android.gms.maps.MapFragment"
    />

    <ImageView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_centerInParent="true"
        Android:src="@drawable/gps"
    />

</RelativeLayout>
8
Andrii Omelchenko