相机动画和用户相机移动的区别

Posted

技术标签:

【中文标题】相机动画和用户相机移动的区别【英文标题】:Difference between camera animation and user camera movement 【发布时间】:2020-03-12 10:42:17 【问题描述】:

我目前在 Flutter 中使用 GoogleMap。我还使用clustering_google_maps 包来显示标记集群。此插件的默认行为是每次相机移动都会触发所有标记和集群的更新。此行为考虑到用户放大/缩小和翻译。

我在 location 包中添加了一项功能,其中相机根据用户的位置移动。

  initPlatformState() async 
    // Wait for the Completer to complete and return the GoogleMap Controler
    mapController = await _controller.future;
    // Set controller for the ClusteringHelper
    clusteringHelper.mapController = mapController;

    // Get database and update markers
    clusteringHelper.database = await DBHelper().database;
    clusteringHelper.updateMap();

    // Set parameters for location Service
    await _locationService.changeSettings(
        accuracy: LocationAccuracy.HIGH, interval: 1000);

    try 
      bool serviceStatus = await _locationService.serviceEnabled();
      print("Service status: $serviceStatus");
      if (serviceStatus) 
        _permission = await _locationService.requestPermission();
        print("Permission: $_permission");

        // If permission granted, get current location and subscribe to updates
        if (_permission) 
          LocationData location = await _locationService.getLocation();

          final myLocationMarkerId = MarkerId("myLocationMarker");
          myLocationMarker = Marker(
              markerId: myLocationMarkerId,
              position: LatLng(location.latitude, location.longitude),
              icon: BitmapDescriptor.defaultMarker,
              infoWindow: InfoWindow(
                  title: "My Location",
                  snippet: "Latitude: " +
                      location.latitude.toString() +
                      " Longitude: " +
                      location.longitude.toString()),
              );

          _locationSubscription = _locationService
              .onLocationChanged()
              .listen((LocationData result) async 
            if (cameraUpdateToMyLocation) 

              _currentCameraPosition = CameraPosition(
                  target: LatLng(result.latitude, result.longitude), zoom: 16);

              // Safety check if mapController not null
              if (mapController != null) 
                mapController.animateCamera(
                    CameraUpdate.newCameraPosition(_currentCameraPosition));
              
            

            if (mounted) 
              setState(() 
                _currentLocation = result;
                myLocationMarker = myLocationMarker.copyWith(
                    positionParam: LatLng(
                        _currentLocation.latitude, _currentLocation.longitude),
                infoWindowParam: InfoWindow(
                    title: "My Location",
                    snippet: "Latitude: " +
                        location.latitude.toString() +
                        " Longitude: " +
                        location.longitude.toString())
                        );

              );
            
          );
        
       else 
        bool serviceStatusResult = await _locationService.requestService();
        print("Service status activated after request: $serviceStatusResult");
        if (serviceStatusResult) 
          initPlatformState();
        
      
     on PlatformException catch (e) 
      print(e);
      if (e.code == 'PERMISSION_DENIED') 
        error = e.message;
       else if (e.code == 'SERVICE_STATUS_ERROR') 
        error = e.message;
      
    
  

我希望当用户在屏幕上移动地图时停止此位置更新。

不幸的是,当用户移动地图和启动相机动画时,会触发回调onCameraMove

是否可以触发 inCameraMove 回调,仅当用户移动地图时?

谢谢!

EDIT当我用手指拖动地图时,似乎循环调用了onCameraMove...

【问题讨论】:

【参考方案1】:

据我所知,无法区分 onCameraMove 回调。你想在这里完成什么?您可以更改插件以显示集群 onCameraIdle 回调吗?这能解决你的问题吗?

【讨论】:

我希望相机跟随用户的位置,直到他拖动地图以查看他的周围。相机应该停留在这个位置,直到用户按下一个按钮,使相机再次跟随它的位置。 我看到我们可以将 Google 地图小部件封装在手势检测器中。是否可以在此处检测平移手势并在此处停止更新用户的相机位置? 这可能行得通。由于您使用 Stream 来获取用户位置,因此您可以暂停流订阅并在用户按下按钮时恢复订阅。让我知道它是否适合你:) 暂停流是个好主意!我没有想到这一点。我想使用布尔值 -_-【参考方案2】:

很遗憾,谷歌地图 Flutter 目前不支持此功能。您可以通过在侦听器中包装一个地图并控制一个布尔值来处理它,该布尔值显示什么样的动作使相机移动。例如,我想知道相机是否通过单击标记移动(调用标记的点击回调移动相机)或用户手动拖动地图。每次用户触摸地图时,我将“dragsTheScreen”布尔值更改为 true,并在标记的点击功能中将其更改为 false,这表明相机移动是由于标记。所以你可以为你想要的任何功能做到这一点。例如,您想查明相机移动是因为调用了您自己的特殊函数还是用户拖动:侦听器将 boolean("dragsTheScreen") 更改为 true,并且该函数将其 setState 更改为 false。

                    Listener(
                  onPointerDown: (PointerDownEvent event)
                    setState(() 
                      dragsTheScreen=false;
                    );
                  ,
                  child: GoogleMap(
                    markers: markerItemsForShow.toSet(),
                    mapType: MapType.normal,
                    onMapCreated: onMapCreated,
                    onCameraMove: onCameraMove,
                    onCameraIdle: onCameraIdle,
                 initialCameraPosition:CameraPosition(tilt:25,target:LatLng(32.71,51.66), zoom: 5),
                  ),
                ),

在我创建它们时点击回调的标记:

markerItemsForShow.add(Marker(
        markerId:...,
        position:...,
      onTap: ()
        setState(() 
          dragsTheScreen=true;
        );
      
    ));

【讨论】:

以上是关于相机动画和用户相机移动的区别的主要内容,如果未能解决你的问题,请参考以下文章

动画相机以定位和设置谷歌地图中的平移

播放相机动画 - 虚幻蓝图

相机移动

Android\iOS 相机权限 - 移动用户无响应

在 Scenekit 中移动相机

移动相机以适应 3D 场景