Android:拖动地图,同时保持标记在中心位置 [英] Android: Drag map while keeping marker at the center

查看:206
本文介绍了Android:拖动地图,同时保持标记在中心位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在正在MapActivity中获取设备的当前位置(lat,lng)。现在我想让用户移动地图,同时将标记保留在中心位置。这意味着无论何时移动地图,当前位置都将被更新。 (右?)

I a, currently getting Current Location of device (lat,lng) in MapActivity. Now I want to let the user move the map, while keeping the marker at the center. This means that whenever the map is moved, current location will be updated. (Right?)

我跟着这个 android如何在标记下移动地图,但无法让我的概念清晰。

I followed this android How to move a map under a marker and How to attach a flexible marker on map something like Uber and Lyft? but couldn't get my concept clear.

Activity_map.xml(这里我添加了ImageView)

Activity_map.xml (Here I have added 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>

我的MapActivity如下

My MapActivity is as follows

 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.
    }
}

您的帮助将不胜感激。谢谢。

Your help will much appreciated. Thank you.

推荐答案

使用标记图标在ImageView下绘制地图将是最好的方法(只是一个框架布局与您的地图片段下和您的标记图像居中顶部应该工作)。然后你可以使用一个 OnCameraIdleListener ,它会在地图移动结束时收到回调。因此,只需将 OnCameraIdleListener 的实例设置为您的地图,即可监听移动回调,如下所示:

Having a map under an ImageView with your marker icon would be the best way to go here (just a framelayout with your map fragment under and your marker image centered on top should work). Then you can use an OnCameraIdleListener which would receive a callback when the map movement has ended. So just set an instance of OnCameraIdleListener to your map to listen for movement callbacks like so:

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

这篇关于Android:拖动地图,同时保持标记在中心位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆