Reputation: 1476
So I'm trying to change my map state using a StreamBuilder by retrieving the user location and adding a marker to the sink. This is my BLoC class:
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);
}
}
This is my 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
},
),
And this is where I call the createMarker method:
FloatingActionButton(
onPressed: () {
_getPositionSubscription = geolocator.getPositionStream().listen((Position currentLocation) {
_customMapBLoC.createMarker(_userPositionId, currentLocation);
});
},
)
This is how I pass the markers map I'm changing in the _customMap class:
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),
);
Why isn't this working? What I'm doing wrong?
This piece of code, using a Firebase stream seems to be working and my own stream doesn't.
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;
},
)
EDIT: Here is the full build method code:
@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),
),
],
)
],
),
);
}
Upvotes: 1
Views: 2480
Reputation: 1476
This is not ideally the right answer as it's not entirely logical. But creating my map inside the builder method seems to be working. The marker also seems to be taking around 5 seconds to show up. Even when the debugPrint shows the data almost instantly as I click the button.
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;
},
),
However, using the same with a different stream. In this case a Firebase store snapshot works without having to create the map inside the builder method.
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
},
),
Upvotes: 1