【问题标题】:Changing google map state in flutter using streambuilder使用streambuilder改变谷歌地图状态
【发布时间】:2019-10-07 10:23:28
【问题描述】:

所以我试图通过检索用户位置并向接收器添加标记来使用 StreamBuilder 更改我的地图状态。这是我的 BLoC 课程:

class CustomMapBLoC {

  StreamController customMapStreamController = StreamController<Marker>.broadcast();
  Sink get customMapSink => customMapStreamController.sink;
  Stream<Marker> get customMapStream => customMapStreamController.stream;

  createMarker(MarkerId markerId, Position position) {
    Marker marker = Marker(
      icon: BitmapDescriptor.defaultMarker,
      markerId: markerId,
      position: LatLng(position.latitude,position.longitude),
    );
    customMapSink.add(marker);
  }

}

这是我的 StreamBuilder:

StreamBuilder(
    stream: _customMapBLoC.customMapStream,
    builder: (context,snapshot) {
      if(snapshot.data != null) {
        _customMap.markersMap[_userPositionId] = snapshot.data;
        debugPrint("SNAPSHOT DATA: ${snapshot.data}"); // These two show the data is received in the console.
        debugPrint("MARKERSMAP: ${_customMap.markersMap}");
      }
      return _customMap; //_customMap is created inside the build method
    },
),

这就是我调用 createMarker 方法的地方:

FloatingActionButton(
    onPressed: () {
      _getPositionSubscription = geolocator.getPositionStream().listen((Position currentLocation) {
        _customMapBLoC.createMarker(_userPositionId, currentLocation);
      });
    },
)

这就是我在 _customMap 类中传递我正在更改的标记图的方式:

static Map<MarkerId, Marker> _markersMap = <MarkerId, Marker>{};

CustomMap(): super(
    mapType: defaultMapType,
    initialCameraPosition: defaultCameraPosition,
    onMapCreated: (GoogleMapController controller) {
      _mapControllerCompleter.complete(controller);
    },
    markers: Set<Marker>.of(_markersMap.values),
);

为什么这不起作用?我做错了什么?

使用 Firebase 流的这段代码似乎可以正常工作,而我自己的流却不行。

StreamBuilder(
    stream: Firestore.instance.collection("users").where("type",isEqualTo: 2).snapshots(),
    builder: (context, snapshot) {
      if(snapshot.data.documents.length > 0) {
        debugPrint("MARKERS: ${_customMap.markersMap}");
        for(var i = 0; i < snapshot.data.documents.length; i++) {
          MarkerId markerId = MarkerId(snapshot.data.documents[i]['uid']);
          Marker marker = new Marker(
            icon: BitmapDescriptor.defaultMarker,
            markerId: markerId ,
            position: LatLng(34.040501,-4.9898821),
          );
          _customMap.markersMap[markerId] = marker;
        }
      }
      return _customMap;
    },
)

编辑:这是完整的构建方法代码:

@override
  Widget build(BuildContext context) {
    CustomMap _customMap = CustomMap();
    _customMapBLoC = new CustomMapBLoC();
    return Scaffold(
      key: scaffoldKey,
      appBar: AppBarLayout(context,"Home",scaffoldKey) ,
      drawer: DrawerLayout(),
      backgroundColor: Colors.grey.shade200,
      body: Stack(
        children: <Widget>[
          StreamBuilder(
            stream: _customMapBLoC.customMapStream,
            builder: (context,snapshot) {
              if(snapshot.data != null) {
                _customMap.markersMap[_userPositionId] = snapshot.data as Marker;
                debugPrint("SNAPSHOT DATA: ${snapshot.data}");
                debugPrint("MARKERSMAP: ${_customMap.markersMap}");
              }
              return _customMap;
            },
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
              Container(
                alignment: Alignment(1.0, 1.0),
                child: SizedBox(
                  height: 35,
                  child: FloatingActionButton(
                    onPressed: () {
                      _getPositionSubscription = geolocator.getPositionStream().listen((Position currentLocation) {
                        _customMapBLoC.createMarker(_userPositionId, currentLocation);
                      });
                    },
                    child: Icon(
                      Icons.location_off,
                      size: 16,
                    ),
                    backgroundColor: Color(0xffF2AB64),
                  )
                ),
              ),
              Padding(
                padding: EdgeInsets.only(top: 14.0),
              ),
            ],
          )
        ],
      ),
    );
}

【问题讨论】:

  • 您的代码中没有addMarker 方法
  • @pskink 只是一个错字,它是 createMarker
  • 有没有调用_customMapBLoC.createMarker?尝试添加一些print('createMarker called') 并检查日志?
  • @pskink 是的,它被称为。在我的StreamBuilder 中,我有一个debugPrint 来查看我是否收到任何数据。它打印在控制台中,但地图似乎没有更新。
  • 那么什么不起作用?你按FloatingActionButton 然后createMarker 被调用,最后StreamBuilder 被重建(它的builder: (context, snapshot) 被调用) - 那么它有什么问题? snapshot 是错误的还是什么?

标签: flutter


【解决方案1】:

这不是理想的正确答案,因为它并不完全合乎逻辑。但是在 builder 方法中创建我的地图似乎是有效的。标记似乎也需要大约 5 秒才能显示出来。即使当我单击按钮时 debugPrint 几乎立即显示数据。

StreamBuilder(
    stream: _customMapBLoC.customMapStream,
    builder: (context,snapshot) {
      CustomMap _customMap = CustomMap(); // This is the newly added line
      if(snapshot.data != null) {
        _customMap.markersMap[_userPositionId] = snapshot.data as Marker;
        debugPrint("SNAPSHOT DATA: ${snapshot.data}");
        debugPrint("MARKERSMAP: ${_customMap.markersMap}");
      }
      return _customMap;
    },
),

但是,对不同的流使用相同的。在这种情况下,Firebase 商店快照无需在 builder 方法中创建地图即可工作。

StreamBuilder(
    stream: Firestore.instance.collection("users").where("type",isEqualTo: 2).snapshots(),
    builder: (context, snapshot) {
      if(snapshot.data.documents.length > 0) {
        debugPrint("MARKERS: ${_initMap.markersMap}");
        for(var i = 0; i < snapshot.data.documents.length; i++) {
          Marker marker = new Marker(
            icon: BitmapDescriptor.defaultMarker,
            markerId: _markerId,
            position: LatLng(34.040501,-4.9898821),
          );
          MarkerId markerId = MarkerId(snapshot.data.documents[i]['uid']);
          _initMap.markersMap[markerId] = marker;
        }
      }
      return _initMap; //This object is created outside the builder method
    },
),

【讨论】:

  • 我在对象创建之后和返回之前添加了一个打印(第一个在 Widget Build 方法中,第二个在 Stream Builder 方法中)。结果是这样的:I/flutter ( 4763): Builder Method: 272475105I/flutter ( 4763): Build Method: 25156775,显然它们不是同一个对象,但是我在builder方法中没有对对象本身进行任何更改,这是怎么回事?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-20
  • 2015-05-28
  • 2020-08-12
相关资源
最近更新 更多