4

My layout

<FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <fragment
                android:id="@+id/map"
                class="com.google.android.gms.maps.SupportMapFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

   <ImageView
                android:id="@+id/pin"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:contentDescription="@null"
                android:src="@drawable/ic_center_pin" />
        </FrameLayout>

Below thing I have tried android How to move a map under a marker

How to attach a flexible marker on map something like Uber and Lyft?

Keep map centered regardless of where you pinch zoom on android

I tried onCameraChangeListener approach,below is the code but experiance is laggy,

private GoogleMap.OnCameraChangeListener cameraChangedListener = new GoogleMap.OnCameraChangeListener() {
        private float previousZoomValue = 17;
        private CameraUpdate cu;

        @Override
        public void onCameraChange(CameraPosition cameraPosition) {


            if (previousZoomValue == cameraPosition.zoom) {
                mLatitude = cameraPosition.target.latitude;
                mLongitude = cameraPosition.target.longitude;
                cu = CameraUpdateFactory.newLatLng(new LatLng(mLatitude,mLongitude));

            } else if (previousZoomValue > cameraPosition.zoom) {
                previousZoomValue = cameraPosition.zoom;
                mGoogleMap.moveCamera(cu);
            } else {
                mGoogleMap.moveCamera(cu);
                previousZoomValue = cameraPosition.zoom;
            }

        }

I want when user taps or pinch to zoom map marker should not move , it should stick to map

Community
  • 1
  • 1
Naga
  • 1,931
  • 4
  • 25
  • 42
  • so you want something in a fixed position over the map? So you don't have to use a marker, but draw a view over the GoogleMap item (something like a frame layout) – N Dorigatti Mar 29 '16 at 12:05

1 Answers1

11

Any approach that relies on map events will be laggy, so I would recommed to create a helper View that manages all the touches and dispatches some of them to the map (panning gestures in this case).

Layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="wrap_content">

    <fragment
        android:id="@+id/map"
        class="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <!-- Helper view to manage touches -->
    <View
        android:id="@+id/helperView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <mypackage.AnchoredImageView
        android:id="@+id/pin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:contentDescription="@null"
        android:src="@drawable/ic_center_pin"/>
</FrameLayout>

On the Activity:

final View mMapView = getSupportFragmentManager().findFragmentById(R.id.map).getView();
View mHelperView = findViewById(R.id.helperView);
mHelperView.setOnTouchListener(new View.OnTouchListener() {
    private float scaleFactor = 1f;

    @Override
    public boolean onTouch(final View view, final MotionEvent motionEvent) {
        if (simpleGestureDetector.onTouchEvent(motionEvent)) { // Double tap
            mMap.animateCamera(CameraUpdateFactory.zoomIn()); // Fixed zoom in
        } else if (motionEvent.getPointerCount() == 1) { // Single tap
            mMapView.dispatchTouchEvent(motionEvent); // Propagate the event to the map (Pan)
        } else if (scaleGestureDetector.onTouchEvent(motionEvent)) { // Pinch zoom
            mMap.moveCamera(CameraUpdateFactory.zoomBy( // Zoom the map without panning it
                    (mMap.getCameraPosition().zoom * scaleFactor
                            - mMap.getCameraPosition().zoom) / 5));
        }

        return true; // Consume all the gestures
    }

    // Gesture detector to manage double tap gestures
    private GestureDetector simpleGestureDetector = new GestureDetector(
            MapsActivity.this, new GestureDetector.SimpleOnGestureListener() {
                @Override
                public boolean onDoubleTap(MotionEvent e) {
                    return true;
                }
            });

    // Gesture detector to manage scale gestures
    private ScaleGestureDetector scaleGestureDetector = new ScaleGestureDetector(
            MapsActivity.this, new ScaleGestureDetector.SimpleOnScaleGestureListener() {
                @Override
                public boolean onScale(ScaleGestureDetector detector) {
                    scaleFactor = detector.getScaleFactor();
                    return true;
                }
            });
});

As the anchor of a ImageView is the center of the image, if we use a image like a pin, the marker will apparently move because the bottom center of the image must be in the center of the map. To avoid this, we can move the image creating an anchored image view.

AnchoredImageView

public class AnchoredImageView extends ImageView {
    public AnchoredImageView(Context context) {
        super(context);
    }

    public AnchoredImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AnchoredImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        setTranslationY(-h/2);
    }
}
antonio
  • 18,044
  • 4
  • 45
  • 61
  • sorry for late reply , let me try this and will let you know sir – Naga Apr 01 '16 at 12:40
  • What gesture is moving your marker? My code must keep the map on the same location when the user zooms using two fingers or double tap. – antonio Apr 01 '16 at 14:30
  • Yes but in both case even user is using two fingers or double tapping , it looks marker pin is getting moved – Naga Apr 01 '16 at 14:57
  • If I understand correctly, the marker seems to move because the marker is centered in the center of the image and it must be centered in the bottom of the image. Please check my edit – antonio Apr 01 '16 at 15:35
  • yes you are right , I will try the edit as well , thank you very much – Naga Apr 02 '16 at 13:32
  • @antonio- looks cool we are very near the only problem is setTranslationY(-h/2) slicing image from half so only half of the image is visible – Naga Apr 02 '16 at 16:58
  • Just for sake of more explanation the drawable ic_center_pin is slicing from half in height only half of the image is visible – Naga Apr 02 '16 at 17:08
  • Ummm... In my tests it shows complete but displaced in the y axis, and the document for `setTranslationY` says that "This effectively positions the object post-layout, in addition to wherever the object's layout placed it". Is `ic_center_pin` a png image? – antonio Apr 02 '16 at 17:36
  • Yes ic_center_pin is a png image, – Naga Apr 02 '16 at 17:44
  • it is really working good , just we need to get the complete image , it will be very helpful for me – Naga Apr 02 '16 at 17:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/108049/discussion-between-antonio-and-naga). – antonio Apr 02 '16 at 17:49