屏幕上的Google Maps Circle中心

时间:2018-09-03 12:20:26

标签: android google-maps

我在Google地图上这样绘制了一个圆圈:

    var circle = CircleOptions().center(googleMap?.cameraPosition?.target)
            .radius(MAX_RADIUS.toDouble())
            .fillColor(ContextCompat.getColor(ctx, R.color.mapCircle))
            .strokeWidth(0f)
    Timber.w("Painting circle!")
    staticCircle = googleMap?.addCircle(circle)

现在,我想将此圆保持在地图中心,所以我这样做了:

 googleMap?.setOnCameraMoveListener {
            var center = googleMap?.cameraPosition?.target

            if (center != null) {
                Timber.v("Centering circle in $center")
                animatedCircle?.center = center
                staticCircle?.center = center
            }
        }

无论如何,运动都是生涩的,并且在发生自动缩放时,圆圈也随相机一起移动,而不是等待其稳定下来。

有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

如何使用 setOnCameraIdleListener 代替 setOnCameraMoveListener ?仅当相机/变焦移动结束时才会触发回调

答案 1 :(得分:0)

更好的方法是将基于MapViewcustom view与覆盖的'dispatchDraw()'(因为MapViewViewGroup)结合使用,从而在其内容上画圈。并应针对当前缩放级别重新计算圆半径。像这样:

public class CustomMapView extends MapView implements OnMapReadyCallback {

    private OnMapReadyCallback mMapReadyCallback;
    private GoogleMap mGoogleMap;
    private int mRadiusInMeters = 500;
    private Paint mPaintCircle;

    public CustomMapView(@NonNull Context context) {
        super(context);
        init();
    }

    public CustomMapView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomMapView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public CustomMapView(@NonNull Context context, @Nullable GoogleMapOptions options) {
        super(context, options);
        init();
    }

    @Override
    public void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        canvas.save();
        drawCircle(canvas);
        canvas.restore();
    }

    private void drawCircle(Canvas canvas) {
        if (mGoogleMap == null) {
            return;
        }

        VisibleRegion visibleRegion = mGoogleMap.getProjection().getVisibleRegion();
        LatLngBounds screenBounds = visibleRegion.latLngBounds;
        LatLng mapCenter = screenBounds.getCenter();
        final Point pointMapCenter = mGoogleMap.getProjection().toScreenLocation(mapCenter);
        final double meters_int_pixel = (Math.cos(mGoogleMap.getCameraPosition().target.latitude * Math.PI /180) * 2 * Math.PI * 6378137)
                / (256 * Math.pow(2, mGoogleMap.getCameraPosition().zoom));
        final int radius = (int)(mRadiusInMeters / meters_int_pixel);
        canvas.drawCircle(pointMapCenter.x, pointMapCenter.y, radius, mPaintCircle);
    }

    private void init() {
        setWillNotDraw(false);

        mPaintCircle = new Paint();
        mPaintCircle.setColor(Color.BLUE);
        mPaintCircle.setStyle(Paint.Style.FILL);
        mPaintCircle.setAlpha(90);
        mPaintCircle.setStrokeWidth(5);
    }

    @Override
    public void getMapAsync(OnMapReadyCallback callback) {
        mMapReadyCallback = callback;
        super.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
        mGoogleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
            @Override
            public void onCameraMove() {
                invalidate();
            }
        });
        if (mMapReadyCallback != null) {
            mMapReadyCallback.onMapReady(googleMap);
        }
    }
}

您可以通过以下方式在MainActivity中使用该自定义视图:

public class MainActivity extends AppCompatActivity {

    private static final String MAP_VIEW_BUNDLE_KEY = "MapViewBundleKey";
    private CustomMapView mMapView;

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

        Bundle mapViewBundle = null;
        if (savedInstanceState != null) {
            mapViewBundle = savedInstanceState.getBundle(MAP_VIEW_BUNDLE_KEY);
        }

        mMapView = (CustomMapView) findViewById(R.id.mapview);
        mMapView.onCreate(mapViewBundle);
        mMapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap googleMap) {
                mGoogleMap = googleMap;
            }
        });

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        Bundle mapViewBundle = outState.getBundle(MAP_VIEW_BUNDLE_KEY);
        if (mapViewBundle == null) {
            mapViewBundle = new Bundle();
            outState.putBundle(MAP_VIEW_BUNDLE_KEY, mapViewBundle);
        }

        mMapView.onSaveInstanceState(mapViewBundle);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    protected void onStart() {
        super.onStart();
        mMapView.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mMapView.onStop();
    }
    @Override
    protected void onPause() {
        mMapView.onPause();
        super.onPause();
    }
    @Override
    protected void onDestroy() {
        mMapView.onDestroy();
        super.onDestroy();
    }
    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }

}

具有布局文件activity_main.xml,例如:

<?xml version="1.0" encoding="utf-8"?>
<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">

    <com.test.just.googlemapsgeneral.views.CustomMapView
        android:id="@+id/mapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />

</RelativeLayout>