簡體   English   中英

如何在android中執行捏合放大或捏合縮小

[英]How to get if pinch zoom in is performed or pinch zoom out in android

我正在開發一個應用程序,在該應用程序中我使用了自定義 mapView,並且在該 mapView 上,如果用戶捏合(兩個手指手勢),地圖的相機位置應該相應地改變,例如。 如果用戶雙指放大,則相機縮放應放大地圖(僅屏幕中心),如果用戶雙指縮小,相機縮放應縮小地圖(僅屏幕中心)。 我已經嘗試過了,但是為了放大和縮小地圖總是在放大。有沒有辦法找到增加/減少的兩個手指之間的距離,或者手勢是捏縮小還是捏放大?

更新

主活動.java

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();
    private static final int LOCATION_PERMISSION_CONSTANT = 34;

    private static final int REQUEST_CHECK_SETTINGS = 12;

    //private EnhanchedMapView mapView;
    private MapView mapView;

    private GoogleMap googleMap;
    private FusedLocationProviderClient mFusedLocationClient;
    private Location mLastLocation;
    LocationManager locationManager;
    private TextView tvCoordinates;
    private GoogleApiClient googleApiClient;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bindUI();
        mapView.onCreate(savedInstanceState);
        fusedLocationMethod(savedInstanceState);
        getLocationPermission();
        //getLastLocation();
    }

    private void bindUI() {
        mapView = findViewById(R.id.map_view);
        tvCoordinates = findViewById(R.id.tv_coordinates);

    }

   public void fusedLocationMethod(Bundle savedInstanceState) {
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    }

    private void getLocationPermission() {
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION},
                    LOCATION_PERMISSION_CONSTANT);
            return;
        }
        getLastLocation();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case LOCATION_PERMISSION_CONSTANT:
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    if (googleApiClient == null) {
                        getLocationPermission();
                    } else {
                        getLocationPermission();
                    }
                } else {

                    Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }


    public void getLastLocation() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }
        mFusedLocationClient.getLastLocation()
                .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        if (location == null) {
                            Log.w(TAG, "onSuccess:null");
                            return;
                        }

                        mLastLocation = location;
                        preLat = location.getLatitude();
                        preLong = location.getLongitude();
                        settingMap(location.getLatitude(), location.getLongitude());

                        try {
                            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
                        } catch (Exception e) {
                            e.printStackTrace();
                            Log.d("Error", e.getMessage() + " 203");
                        }

                        if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

                            return;
                        }

                    }
                })
                .addOnFailureListener(this, new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.w(TAG, "getLastLocation:onFailure", e);
                    }
                });
    }

    private double preLat = 0.0;
    private double preLong = 0.0;

    //setting map
    private void settingMap(final double lat, final double longi) {
        mapView.getMapAsync(new OnMapReadyCallback() {


            @Override
            public void onMapReady(GoogleMap gglmap) {


                googleMap = gglmap;
                googleMap.getUiSettings().setAllGesturesEnabled(false);
                googleMap.clear();
                CameraPosition cameraPosition = new CameraPosition.Builder().target(new LatLng(lat, longi)).zoom(16).build();

                googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

                googleMap.getUiSettings().setMyLocationButtonEnabled(false);

                //permission for location
                if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

                    return;
                }
                googleMap.setMyLocationEnabled(true);


                //googleMap.getUiSettings().setAllGesturesEnabled(false);
                googleMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
                    @Override
                    public void onCameraIdle() {

                        int mapViewHeight = mapView.getHeight();
                        int mapViewWidth = mapView.getWidth();

                        Projection projection = googleMap.getProjection();

                        LatLng geographicalPosition = projection.fromScreenLocation(new Point(mapViewWidth / 2, mapViewHeight / 2));
                        //     Toast.makeText(getActivity(),""+geographicalPosition.latitude+" , "+geographicalPosition.longitude,Toast.LENGTH_LONG).show();


                        tvCoordinates.setText(geographicalPosition.latitude + "   ,   " + geographicalPosition.longitude);
                    }
                });

            }
        });


    }


    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
    }


    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        mapView.onSaveInstanceState(savedInstanceState);
    }

    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    public void onStop() {
        super.onStop();
        mapView.onStop();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    public void onStart() {
        super.onStart();
        mapView.onStart();
    }


}

增強的MapView.java

public class EnhanchedMapView extends MapView implements OnMapReadyCallback {
    private long mLastTouchTime = -1;
    private static final int INVALID_POINTER_ID = -1;

    private OnMapReadyCallback mMapReadyCallback;
    private GoogleMap mGoogleMap;

    private float mPosX;
    private float mPosY;

    private float mLastTouchX;
    private float mLastTouchY;
    private int mActivePointerId = INVALID_POINTER_ID;

    private void init() {
    }

    @Override
    public void getMapAsync(OnMapReadyCallback callback) {
        mMapReadyCallback = callback;

        super.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
    }

    LatLng geographicalPosition;
    boolean isPinch = false;

    @Override
    public boolean dispatchTouchEvent(MotionEvent 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));

                        MarkerOptions markerOptions = new MarkerOptions();
                        markerOptions.position(geographicalPosition);
                        mGoogleMap.addMarker(markerOptions);
                        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);
                Log.d("Nirmal", "ACTION_POINTER_DOWN");
                isPinch = true;

                int mapViewHeight = getHeight();
                int mapViewWidth = getWidth();

                Projection projection = mGoogleMap.getProjection();

                geographicalPosition = projection.fromScreenLocation(new Point(mapViewWidth / 2, mapViewHeight / 2));


                break;

            case MotionEvent.ACTION_POINTER_UP:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);

                isPinch = false;
                break;

            case MotionEvent.ACTION_UP:
                mGoogleMap.getUiSettings().setScrollGesturesEnabled(true);
                break;

            case MotionEvent.ACTION_MOVE:
                if (isPinch) {
                    if (mGoogleMap == null || geographicalPosition == null)
                        break;
                    //Log.d("Nirmal", "ACTION_MOVE");
                    Log.d("Nirmal", "" + event.getX() + " , " + event.getY());


                    float currentZoom = mGoogleMap.getCameraPosition().zoom;

                    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(geographicalPosition.latitude, geographicalPosition.longitude), currentZoom + 0.05f));

                }
                break;

        }

        return super.dispatchTouchEvent(event);
    }


}

正如pskink推薦的那樣,您需要ScaleGestureDetector對象,該對象確定縮放“方向”。 類似的東西:

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();
                return true;
            }

            @Override
            public void onScaleEnd(ScaleGestureDetector detector) {
                float currentZoom = mGoogleMap.getCameraPosition().zoom;
                if (scaleFactor > 1) {
                    // zoom in detected
                    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mZoomCenter, currentZoom + 1));
                } else if (scaleFactor < 1) {
                    // zoom out detected
                    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mZoomCenter, currentZoom - 1));
                }
                super.onScaleEnd(detector);
            }
        });

您可以輕松地在您的EnhanchedMapView.dispatchTouchEvent()使用它:

...
@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    // just call .onTouchEvent() on your ScaleGestureDetector object
    mScaleDetector.onTouchEvent(event);

    switch (event.getAction() & MotionEvent.ACTION_MASK) {
    ...

注意! 您需要禁用GoogleMap縮放手勢

@Override
public void onMapReady(GoogleMap googleMap) {
    mGoogleMap = googleMap;
    mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);
    ...
}

並且永遠不要啟用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM