如何检查标记是否在反应本地地图的屏幕上显示的区域中

问题描述

我在底部的FlatList中水平显示了项目列表,并在地图中显示了所有标记。现在,用户可以自由放大/缩小地图,或者单击任何标记底部的FlatList滚动到项目。用户还可以滚动FlatList并根据索引标记进行选择。当列表很大且用户已手动放大地图时。

现在的问题是,用户可以缩放地图上的任何位置,并且当用户滑动下面的列表并更改项目索引时,我需要能够检查该标记是否在屏幕上以及是否无法缩放到该标记。 / p>

因此我可以使用以下代码手动缩放区域。

  const animateMapToRegion = (region = null,duration = 1000) => {
    if (region) {
      mapRef.current.animatetoRegion(region,duration);
    }
  };

仅当标记不在屏幕上时,才需要执行此动画。我检查了文档,却找不到任何功能来检查屏幕上是否有标记

我只想在屏幕上看不到标记时进行动画处理。请协助。

解决方法

最后,我为iOS和Android添加了自己的实现。

在AIRGoogleMapManager.m中添加以下方法

RCT_EXPORT_METHOD(isMarkerWithinScreen:(nonnull NSNumber *)reactTag
                  position:(CLLocationCoordinate2D)position
                  resolver: (RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
  [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager,NSDictionary<NSNumber *,UIView *> *viewRegistry) {
    id view = viewRegistry[reactTag];
    if (![view isKindOfClass:[AIRGoogleMap class]]) {
      RCTLogError(@"Invalid view returned from registry,expecting AIRMap,got: %@",view);
    } else {
      AIRGoogleMap *mapView = (AIRGoogleMap *)view;

      GMSVisibleRegion region = [mapView.projection visibleRegion];
      GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithRegion:region];
        
      resolve(@{@"visible": @([bounds containsCoordinate:position])});
    }
  }];
}

在AirMapModule.java中添加以下方法

 @ReactMethod
  public void isMarkerWithinScreen(final int tag,ReadableMap coordinate,final Promise promise) {
    final ReactApplicationContext context = getReactApplicationContext();

    final double lat = coordinate.getDouble("latitude");
    final double lng = coordinate.getDouble("longitude");
    final LatLng position = new LatLng(lat,lng);

    UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class);
    uiManager.addUIBlock(new UIBlock()
    {
      @Override
      public void execute(NativeViewHierarchyManager nvhm)
      {
        AirMapView view = (AirMapView) nvhm.resolveView(tag);
        if (view == null)
        {
          promise.reject("AirMapView not found");
          return;
        }
        if (view.map == null)
        {
          promise.reject("AirMapView.map is not valid");
          return;
        }

        LatLngBounds currentScreen = view.map.getProjection().getVisibleRegion().latLngBounds;
        boolean onScreen = currentScreen.contains(position);

        WritableMap visibleJson = new WritableNativeMap();
        visibleJson.putBoolean("visible",onScreen);

        promise.resolve(visibleJson);
      }
    });
  }

添加最后添加到下面的node_modules / react-native-maps / lib / components / MapView.js

isMarkerWithinScreen(marker) {
    if (Platform.OS === 'android') {
      return NativeModules.AirMapModule.isMarkerWithinScreen(
        this._getHandle(),marker.coordinate
      );
    } else if (Platform.OS === 'ios') {
      return this._runCommand('isMarkerWithinScreen',[marker.coordinate]);
    }
    return Promise.reject('isMarkerWithinScreen not supported on this platform');
  }

现在您可以将其用作

  const marker = //your marker;
  const visibility = await mapRef.current.isMarkerWithinScreen(marker);
  const {visible} = visibility;
  console.log('visible-->',visible); //If visible is true marker is on screen otherwise its not.

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...