我正在使用自定义mapView的应用程序,并且在该mapView上如果用户捏(两个手指手势),地图的相机位置应该相应地改变,例如。如果用户捏放大,则相机变焦应放大地图(仅屏幕中心),如果用户捏缩放,则应缩小相机变焦以适应地图(仅限屏幕中心)。我已经尝试过但是为了放大和缩小地图总是放大。有没有办法找到两个手指之间的距离增加/减少,或手势是捏缩放还是捏放大? ?
更新
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int LOCATION_PERMISSION_CONSTANT = 34;
private static final int REQUEST_CHECK_SETTINGS = 12;
//private EnhanchedMapView mapView;
private MapView mapView;
private GoogleMap googleMap;
private FusedLocationProviderClient mFusedLocationClient;
private Location mLastLocation;
LocationManager locationManager;
private TextView tvCoordinates;
private GoogleApiClient googleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindUI();
mapView.onCreate(savedInstanceState);
fusedLocationMethod(savedInstanceState);
getLocationPermission();
//getLastLocation();
}
private void bindUI() {
mapView = findViewById(R.id.map_view);
tvCoordinates = findViewById(R.id.tv_coordinates);
}
public void fusedLocationMethod(Bundle savedInstanceState) {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}
private void getLocationPermission() {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION},
LOCATION_PERMISSION_CONSTANT);
return;
}
getLastLocation();
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case LOCATION_PERMISSION_CONSTANT:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (googleApiClient == null) {
getLocationPermission();
} else {
getLocationPermission();
}
} else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
break;
}
}
public void getLastLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location == null) {
Log.w(TAG, "onSuccess:null");
return;
}
mLastLocation = location;
preLat = location.getLatitude();
preLong = location.getLongitude();
settingMap(location.getLatitude(), location.getLongitude());
try {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
} catch (Exception e) {
e.printStackTrace();
Log.d("Error", e.getMessage() + " 203");
}
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "getLastLocation:onFailure", e);
}
});
}
private double preLat = 0.0;
private double preLong = 0.0;
//setting map
private void settingMap(final double lat, final double longi) {
mapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap gglmap) {
googleMap = gglmap;
googleMap.getUiSettings().setAllGesturesEnabled(false);
googleMap.clear();
CameraPosition cameraPosition = new CameraPosition.Builder().target(new LatLng(lat, longi)).zoom(16).build();
googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
googleMap.getUiSettings().setMyLocationButtonEnabled(false);
//permission for location
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
googleMap.setMyLocationEnabled(true);
//googleMap.getUiSettings().setAllGesturesEnabled(false);
googleMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
@Override
public void onCameraIdle() {
int mapViewHeight = mapView.getHeight();
int mapViewWidth = mapView.getWidth();
Projection projection = googleMap.getProjection();
LatLng geographicalPosition = projection.fromScreenLocation(new Point(mapViewWidth / 2, mapViewHeight / 2));
// Toast.makeText(getActivity(),""+geographicalPosition.latitude+" , "+geographicalPosition.longitude,Toast.LENGTH_LONG).show();
tvCoordinates.setText(geographicalPosition.latitude + " , " + geographicalPosition.longitude);
}
});
}
});
}
@Override
public void onResume() {
super.onResume();
mapView.onResume();
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
mapView.onSaveInstanceState(savedInstanceState);
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
}
@Override
public void onStop() {
super.onStop();
mapView.onStop();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
@Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
public void onStart() {
super.onStart();
mapView.onStart();
}
}
EnhancedMapView.java
public class EnhanchedMapView extends MapView implements OnMapReadyCallback {
private long mLastTouchTime = -1;
private static final int INVALID_POINTER_ID = -1;
private OnMapReadyCallback mMapReadyCallback;
private GoogleMap mGoogleMap;
private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private void init() {
}
@Override
public void getMapAsync(OnMapReadyCallback callback) {
mMapReadyCallback = callback;
super.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
}
LatLng geographicalPosition;
boolean isPinch = false;
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
long thisTime = System.currentTimeMillis();
if (thisTime - mLastTouchTime < ViewConfiguration.getDoubleTapTimeout()) {
if (mGoogleMap != null) {
LatLng zoomCenter = mGoogleMap.getProjection().fromScreenLocation(new Point((int) event.getX(), (int) event.getY()));
float currentZoom = mGoogleMap.getCameraPosition().zoom;
int mapViewHeight = getHeight();
int mapViewWidth = getWidth();
Projection projection = mGoogleMap.getProjection();
geographicalPosition = projection.fromScreenLocation(new Point(mapViewWidth / 2, mapViewHeight / 2));
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(geographicalPosition);
mGoogleMap.addMarker(markerOptions);
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(geographicalPosition.latitude, geographicalPosition.longitude), currentZoom + 1));
}
mLastTouchTime = -1;
} else {
mLastTouchTime = thisTime;
mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);
mGoogleMap.getUiSettings().setScrollGesturesEnabled(false);
Log.d("Nirmal", "ACTION_POINTER_DOWN");
isPinch = true;
int mapViewHeight = getHeight();
int mapViewWidth = getWidth();
Projection projection = mGoogleMap.getProjection();
geographicalPosition = projection.fromScreenLocation(new Point(mapViewWidth / 2, mapViewHeight / 2));
break;
case MotionEvent.ACTION_POINTER_UP:
mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
isPinch = false;
break;
case MotionEvent.ACTION_UP:
mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
break;
case MotionEvent.ACTION_MOVE:
if (isPinch) {
if (mGoogleMap == null || geographicalPosition == null)
break;
//Log.d("Nirmal", "ACTION_MOVE");
Log.d("Nirmal", "" + event.getX() + " , " + event.getY());
float currentZoom = mGoogleMap.getCameraPosition().zoom;
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(geographicalPosition.latitude, geographicalPosition.longitude), currentZoom + 0.05f));
}
break;
}
return super.dispatchTouchEvent(event);
}
}
答案 0 :(得分:2)
建议pskink,您需要ScaleGestureDetector
对象,它确定缩放“方向”。这样的事情:
ScaleGestureDetector mScaleDetector = new ScaleGestureDetector(getContext(),
new ScaleGestureDetector.SimpleOnScaleGestureListener() {
private float scaleFactor = 1f;
@Override
public boolean onScale(ScaleGestureDetector detector) {
// store scale factor for detect zoom "direction" on end
scaleFactor = detector.getScaleFactor();
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
float currentZoom = mGoogleMap.getCameraPosition().zoom;
if (scaleFactor > 1) {
// zoom in detected
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mZoomCenter, currentZoom + 1));
} else if (scaleFactor < 1) {
// zoom out detected
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mZoomCenter, currentZoom - 1));
}
super.onScaleEnd(detector);
}
});
您可以轻松地在EnhanchedMapView.dispatchTouchEvent()
中使用它:
...
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// just call .onTouchEvent() on your ScaleGestureDetector object
mScaleDetector.onTouchEvent(event);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
...
NB!您需要停用GoogleMap
缩放手势
@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);
...
}
并且从不启用它。