Flutter - обеспечение обновлений карт Google в режиме реального времени с помощью StreamBuilder - PullRequest
0 голосов
/ 28 апреля 2020

В настоящее время я создаю приложение, которое отображает маркеры на карте Google. Расположение маркеров извлекается из базы данных Firestore. В настоящее время я успешно извлекаю и отображаю все маркеры. Однако мне нужно обновить значок каждого маркера в соответствии с его логическим значением в базе данных.

Вот как я сейчас отображаю маркеры.

Я создаю карту в основной сборке :

Container(
          height: MediaQuery.of(context).size.height,
          width: MediaQuery.of(context).size.width,
          child: mapToggle
              ? GoogleMap(
            onMapCreated: onMapCreated,
            compassEnabled: false,
            polylines: route,
            initialCameraPosition: CameraPosition(
                target: LatLng(currentLocation.latitude,
                    currentLocation.longitude),
                zoom: 12),
            markers: markers,
          )
              : Center(
            child: Text('Loading... Please wait...',
                style: TextStyle(fontSize: 20.0)),
          )),

Затем я вызываю эту функцию в initState, чтобы захватить мои маркеры:

chargePoints() {
_database.collection('charge_points').getDocuments().then((docs) {
  if (docs.documents.isNotEmpty) {
    for (int i = 0; i < docs.documents.length; i++) {
      initMarker(docs.documents[i].data, docs.documents[i].documentID);
    }
  }
});

Наконец, функция initMarker добавляет каждый маркер в маркер Set, взятый Google Map. экземпляр:

void initMarker(chargePoint, documentID) {
var markerIdVal = documentID;
final MarkerId markerId = MarkerId(markerIdVal);

// Creating a new Charge Point Marker
final Marker marker = Marker(
    markerId: markerId,
    icon: markerIcon,
    position: LatLng(chargePoint['location'].latitude,
        chargePoint['location'].longitude),
    infoWindow: InfoWindow(
        title: chargePoint['name'], snippet: chargePoint['type']),
    onTap: () {
      findBookings(context, chargePoint, documentID);
    });

setState(() {
  markers.add(marker);
});

Итак, мой вопрос; как я могу вернуть эти данные в виде потока и предоставить слушателю, который обновляет соответствующий значок маркера, когда поле «занят» было изменено?

Firestore

Пользовательский интерфейс карты

1 Ответ

0 голосов
/ 29 апреля 2020

Хорошо, у меня есть решение!

Я сейчас возвращаю StreamBuilder в виджете основной сборки, который принимает запрос Firestore, чтобы вернуть сведения обо всех маркерах.

Затем я использую моментальный снимок, предоставленный потоком для периодического преобразования состояния всех маркеров, установленных выше в функции initMarker.

Кроме того, набор маркеров теперь является картой. Это имеет больше смысла для доступа к маркерам для выполнения обновлений.

Map<MarkerId, Marker> markers = <MarkerId, Marker>{};

Управление маркерами осуществляется с использованием их MarkerId, который соответствует documentID всех результатов, возвращаемых в моментальном снимке.

Дон Я не верю, что это решение идеально, но я надеюсь, что помог кому-то!

StreamBuilder<QuerySnapshot>(
      stream: _servicesObj.getChargePoints(),
      builder:
          (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (!snapshot.hasData) {
          return Text('Loading Points');
        }

        snapshot.data.documents.forEach((change) {
          var markerIdVal = change.documentID;
          final MarkerId markerId = MarkerId(markerIdVal);

          if (change.data['occupied'] == true) {
            markers[markerId] = Marker(
                markerId: markerId,
                icon: pointOccupiedIcon,
                position: LatLng(change.data['location'].latitude,
                    change.data['location'].longitude),
                infoWindow: InfoWindow(
                    title: change.data['name'],
                    snippet: change.data['type']),
                onTap: () {
                  findBookings(context, change.data, change.documentID);
                });
          } else {
            markers[markerId] = Marker(
                markerId: markerId,
                icon: pointAvailableIcon,
                position: LatLng(change.data['location'].latitude,
                    change.data['location'].longitude),
                infoWindow: InfoWindow(
                    title: change.data['name'],
                    snippet: change.data['type']),
                onTap: () {
                  findBookings(context, change.data, change.documentID);
                });
          }
        });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...