在我当前的Android应用程序中,用户可以选择通过将标记放在地图上来选择他们的地址。标记始终位于地图的中心。当用户尝试使用手势(捏住地图)放大位置时,标记正在改变其位置,而使用缩放按钮一切都很好。如何通过在使用单个手指时移动标记并仅在使用多个手指时应用手势来避免在手势情况下移动标记。
答案 0 :(得分:0)
创建TouchableWrapper
并在MapFragment中使用它
public class TouchableWrapper extends FrameLayout {
private GoogleMap mGoogleMap = null;
public TouchableWrapper(Context context) {
super(context);
}
public void setGoogleMap(GoogleMap googleMap) {
mGoogleMap = googleMap;
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
mScaleDetector.onTouchEvent(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));
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);
break;
case MotionEvent.ACTION_POINTER_UP:
mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
break;
case MotionEvent.ACTION_UP:
mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
break;
}
return super.dispatchTouchEvent(event);
}
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();
float currentZoom = mGoogleMap.getCameraPosition().zoom;
int mapViewHeight = getHeight();
int mapViewWidth = getWidth();
if (scaleFactor > 1) {
// zoom in detected
geographicalPosition = mGoogleMap.getProjection().fromScreenLocation(new Point(mapViewWidth / 2, mapViewHeight / 2));
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(geographicalPosition, currentZoom + 0.05f));
} else if (scaleFactor < 1) {
// zoom out detected
geographicalPosition = mGoogleMap.getProjection().fromScreenLocation(new Point(mapViewWidth / 2, mapViewHeight / 2));
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(geographicalPosition, currentZoom - 0.05f));
}
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
super.onScaleEnd(detector);
}
});
}
MapFragment
应该像以下一样定制:
public class MultiTouchMapFragment extends MapFragment {
public View mOriginalContentView;
public TouchableWrapper mTouchView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState);
mTouchView = new TouchableWrapper(getActivity());
mTouchView.addView(mOriginalContentView);
return mTouchView;
}
@Override
public View getView() {
return mOriginalContentView;
}
}
MainActivity
中的:
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mGoogleMap;
private MultiTouchMapFragment mMapFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMapFragment = (MultiTouchMapFragment) getFragmentManager()
.findFragmentById(R.id.map_fragment);
mMapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mMapFragment.mTouchView.setGoogleMap(mGoogleMap);
}
}