谷歌地图圆圈在屏幕上的中心



我在谷歌地图上画了一个圆圈,如下所示:

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

然而,移动是生涩的,而且当自动变焦发生时,圆圈会随着相机移动,而不是等待它安定下来。

有没有更好的方法可以做到这一点?

使用setOnCameraIdleListener而不是setOnCameraMoveListener怎么样?仅当相机/变焦的移动结束时才会触发回调

更好的方法是使用基于MapView的自定义视图和覆盖的"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>

相关内容

  • 没有找到相关文章

最新更新