在谷歌地图中使用捏合放大并缩小,当前位置为地图的中心

时间:2018-02-26 10:33:51

标签: android google-maps zoom gesture marker

在我当前的Android应用程序中,用户可以选择通过将标记放在地图上来选择他们的地址。标记始终位于地图的中心。当用户尝试使用手势(捏住地图)放大位置时,标记正在改变其位置,而使用缩放按钮一切都很好。如何通过在使用单个手指时移动标记并仅在使用多个手指时应用手势来避免在手势情况下移动标记。

1 个答案:

答案 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);
    }

}