Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
463 views
in Technique[技术] by (71.8m points)

android - Pinch to zoom google map with out moving marker in framelayout

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...