android - expand and shrink circle on google map

本秂侑毒 提交于 2019-12-11 18:25:39

问题


I'm trying to draw a resizable circle on google map, which the user will be able to expand or shrink using touch gestures and also want it to work like zooming in/out option in the map, only that just the circle will get bigger/smaller on the map.

I can draw a circle on the map but i don't know how to get it to respond to touch events.

Here is my code

MainActivity.java

    public class MainActivity extends FragmentActivity implements LocationListener {

    GoogleMap googleMap;

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

        // Getting Google Play availability status
        int status = GooglePlayServicesUtil
                .isGooglePlayServicesAvailable(getBaseContext());

        // Showing status
        if (status != ConnectionResult.SUCCESS) { // Google Play Services are
                                                    // not available

            int requestCode = 10;
            Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this,
                    requestCode);
            dialog.show();

        } else { // Google Play Services are available

            // Getting reference to the SupportMapFragment of activity_main.xml
            SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map);

            // Getting GoogleMap object from the fragment
            googleMap = fm.getMap();

            // Enabling MyLocation Layer of Google Map
            googleMap.setMyLocationEnabled(true);

            // Getting LocationManager object from System Service
            // LOCATION_SERVICE
            LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

            // Creating a criteria object to retrieve provider
            Criteria criteria = new Criteria();

            // Getting the name of the best provider
            String provider = locationManager.getBestProvider(criteria, true);

            // Getting Current Location
            Location location = locationManager.getLastKnownLocation(provider);

            if (location != null) {
                onLocationChanged(location);
            }

            locationManager.requestLocationUpdates(provider, 20000, 0, this);
        }

    }

    @Override
    public void onLocationChanged(Location location) {

        // TextView tvLocation = (TextView) findViewById(R.id.tv_location);

        // Getting latitude of the current location
        double latitude = location.getLatitude();

        // Getting longitude of the current location
        double longitude = location.getLongitude();

        // Creating a LatLng object for the current location
        LatLng latLng = new LatLng(latitude, longitude);

        // Showing the current location in Google Map
        googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));

        // Zoom in the Google Map
        googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));

        // Setting latitude and longitude in the TextView tv_location
        // tvLocation.setText("Latitude:" + latitude + ", Longitude:"+ longitude
        // );

    }

    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

Main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

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

  <in.locationingooglemapv2.CircleTouchView
        android:id="@+id/circle_drawer_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" android:focusable="false"/>


</RelativeLayout>

CircleTouchView.java

package in.locationingooglemapv2;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class CircleTouchView extends View {

private static final String TAG = "CircleView";
private static final double MOVE_SENSITIVITY = 1.25;
private Paint circlePaint;
private boolean isPinchMode;
private int lastCircleX;
private int lastCircleY;
public Circle circle;
private boolean isDoneResizing = true;

public CircleTouchView(Context context) {
    super(context);
    setCirclePaint(0x220000ff);
}

public CircleTouchView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setCirclePaint(0x220000ff);
}

public CircleTouchView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    setCirclePaint(0x220000ff);
}

private void setCirclePaint(int color) {
    circle = new Circle();
    circlePaint = new Paint();
    circlePaint.setColor(color);
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawCircle(circle.centerX, circle.centerY, circle.radius, circlePaint);      
}

@Override
public boolean onTouchEvent(final MotionEvent event) {

    int historySize;
    double lastDistance;
    double oneBeforeLastDistance;

    switch (event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:
            lastCircleX = circle.centerX;
            lastCircleY = circle.centerY;
            break;

        case MotionEvent.ACTION_POINTER_DOWN:
            isPinchMode = true;
            isDoneResizing = false;
            break;

        case MotionEvent.ACTION_MOVE:
            circle.centerX = lastCircleX;
            circle.centerY = lastCircleY;; 

            if (getTouchedCircle((int) event.getX(), (int) event.getY()) && !isPinchMode && isDoneResizing) {

                historySize = event.getHistorySize();
                if (historySize > 0) {

                    oneBeforeLastDistance = Math.sqrt((event.getX() - event.getHistoricalX(0, historySize - 1)) * 
                                                      (event.getX() - event.getHistoricalX(0, historySize - 1)) + 
                                                      (event.getY() - event.getHistoricalY(0, historySize - 1)) * 
                                                      (event.getY() - event.getHistoricalY(0, historySize - 1)));


                    if (oneBeforeLastDistance > MOVE_SENSITIVITY) {
                        circle.centerX = (int) event.getX();
                        circle.centerY = (int) event.getY();
                        lastCircleX = circle.centerX;
                        lastCircleY = circle.centerY;

                    }
                }
            }
            if (isPinchMode) {
                circle.centerX = lastCircleX;
                circle.centerY = lastCircleY;

                historySize = event.getHistorySize();
                if (historySize > 0) {

                    lastDistance = Math.sqrt((event.getX(0) - event.getX(1)) * (event.getX(0) - event.getX(1)) + 
                                             (event.getY(0) - event.getY(1)) * (event.getY(0) - event.getY(1)));

                    oneBeforeLastDistance = Math.sqrt((event.getHistoricalX(0, historySize - 1) - event.getHistoricalX(1, historySize - 1)) * 
                                                      (event.getHistoricalX(0, historySize - 1) - event.getHistoricalX(1, historySize - 1)) + 
                                                      (event.getHistoricalY(0, historySize - 1) - event.getHistoricalY(1, historySize - 1)) * 
                                                      (event.getHistoricalY(0, historySize - 1) - event.getHistoricalY(1, historySize - 1)));


                    if (lastDistance < oneBeforeLastDistance) {
                        circle.radius -= Math.abs(lastDistance - oneBeforeLastDistance);
                    } else {
                        circle.radius += Math.abs(lastDistance - oneBeforeLastDistance);
                    }
                }
            }
            lastCircleX = circle.centerX;
            lastCircleY = circle.centerY;
            invalidate();
            break;

        case MotionEvent.ACTION_POINTER_UP:
            circle.centerX = lastCircleX;
            circle.centerY = lastCircleY;
            isPinchMode = false;
            break;

        case MotionEvent.ACTION_UP:
            circle.centerX = lastCircleX;
            circle.centerY = lastCircleY;
            isPinchMode = false;
            isDoneResizing = true;
            break;

        case MotionEvent.ACTION_CANCEL:
            break;

        case MotionEvent.ACTION_HOVER_MOVE:
            break;

        default:
            super.onTouchEvent(event);
            break;
    }
    return true;
}

private Boolean getTouchedCircle(final int xTouch, final int yTouch) {
    if ((circle.centerX - xTouch) * (circle.centerX - xTouch) + 
        (circle.centerY - yTouch) * (circle.centerY - yTouch)   <= circle.radius * circle.radius) {
        return true;
    } else {
        return false;
    }

}

static class Circle {
    int radius;
    int centerX;
    int centerY;

    Circle() {
        this.radius = 150;
        this.centerX = 378;
        this.centerY = 478;
    }        
}
}

/*extends View {
    private static final int MODE_PINCH = 0;
    private static final int MODE_DONT_CARE = 1;

    ShapeDrawable mCircleDrawable;
    int mTouchMode = MODE_DONT_CARE;

    public CircleTouchView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mCircleDrawable = new ShapeDrawable(new OvalShape());
        mCircleDrawable.getPaint().setColor(0x66FFFFFF);
    }

    public CircleTouchView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleTouchView(Context context) {
        this(context, null, 0);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:
            mCircleDrawable.setBounds(0, 0, 0, 0);
            invalidate();
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            prepareCircleDrawing(event);
            break;
        case MotionEvent.ACTION_MOVE:
            if (mTouchMode == MODE_PINCH) {
                prepareCircleDrawing(event);
            }
            break;
        case MotionEvent.ACTION_POINTER_UP:
            if (event.getActionIndex() <= 1) {
                mTouchMode = MODE_DONT_CARE;
            }
            break;
        default:
            super.onTouchEvent(event);
        }

        return true;
    }

    private void prepareCircleDrawing(MotionEvent event) {
        int top, right, bottom, left;
        int index = event.getActionIndex();

        if (index > 1) {
            return;
        }
        mTouchMode = MODE_PINCH;
        if (event.getX(0) < event.getX(1)) {
            left = (int) event.getX(0);
            right = (int) event.getX(1);
        } else {
            left = (int) event.getX(1);
            right = (int) event.getX(0);
        }

        if (event.getY(0) < event.getY(1)) {
            top = (int) event.getY(0);
            bottom = (int) event.getY(1);
        } else {
            top = (int) event.getY(1);
            bottom = (int) event.getY(0);
        }

        mCircleDrawable.setBounds(left, top, right, bottom);

        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mCircleDrawable.draw(canvas);
    }

}
*/

Thanks in advance

来源:https://stackoverflow.com/questions/23954209/android-expand-and-shrink-circle-on-google-map

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!