В моем текущем приложении для Android у пользователя будет возможность выбрать свой адрес, поместив маркер на карту. Маркер всегда остается в центре карты. Когда пользователь пытается увеличить местоположение с помощью жестов (зажимая карту), маркер меняет свое положение, при использовании кнопок масштабирования все в порядке. Как избежать перемещения маркера в случае жеста, перемещая маркер при использовании одного пальца и применяя жесты только при использовании нескольких пальцев.

-4
Nirmal Kumar A 26 Фев 2018 в 13:33

1 ответ

Лучший ответ

Создайте 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);
    }

}
-1
Nirmal Prajapat 27 Фев 2018 в 13:35