Android:拖动地图,同时保持标记在中心位置 [英] Android: Drag map while keeping marker at the center
问题描述
我现在正在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屋!