Flutter — автоматическое обновление значка маркера на карте через определенный промежуток времени

#android #google-maps #flutter #dart #google-maps-markers

#Android #google-карты #трепетать #дротик #google-карты-маркеры #flutter #dart

Вопрос:

У меня есть несколько маркеров, и значки маркеров меняются в зависимости от поля firebase (называемого статусом). статус — это bool (true/false). Это значение статуса очень часто изменяется в базе данных внешним приложением, поэтому мне нужно иметь возможность обновлять значок на основе текущего значения поля. Как я могу автоматически обновлять маркеры в своем пользовательском интерфейсе?

Вот мой код:

 BitmapDescriptor customFreeLotIcon, customOccupiedLotIcon;
Future<List<Marker>> _createMarkersForLotsAndParkings() async{
   List<Marker> markersList = [];
   int markerId = 0;
    QuerySnapshot subDocuments = await parkingDocReference.collection("lots").get();
    List<DocumentSnapshot> subDocumentsSnapshots = subDocuments.documents;
    for (DocumentSnapshot subDoc in subDocumentsSnapshots){
         String subDocId = subDoc.documentID;
         DocumentSnapshot snapshot = await parkingDocReference.collection("lots")
         .document(subDocId).get();
            print(snapshot.get('location').latitude);
            markersList.add(
              Marker(
                  markerId:MarkerId(markerId.toString()),
                  position: LatLng(snapshot.get('location').latitude,
                      snapshot.get('location').longitude),
                  onTap: () => _changeMap(LatLng(
                      snapshot.get('location').latitude,
                      snapshot.get('location').longitude)),
                  icon: snapshot.get('status') == true ? customOccupiedLotIcon : customFreeLotIcon ),
            );
            markerId  ;      
     }
}
return Future.value(markersList);

}


 createCustomImageForParkingsMarkers(context){
    if (customFreeLotIcon == null) {
      ImageConfiguration configuration = createLocalImageConfiguration(context);
      BitmapDescriptor.fromAssetImage(configuration, 'assets/freeLots.png')
          .then((icon) {
        setState(() {
          customFreeLotIcon = icon;
        });
      });
    }
    else if (customOccupiedLotIcon == null) {
      ImageConfiguration configuration = createLocalImageConfiguration(context);
      BitmapDescriptor.fromAssetImage(configuration, 'assets/occupiedLots.png')
          .then((icon) {
        setState(() {
          customOccupiedLotIcon = icon;
        });
      });
    }
  }
  

Ответ №1:

Попробуйте добавить слушателя:

 BitmapDescriptor customFreeLotIcon, customOccupiedLotIcon;
Future<List<Marker>> _createMarkersForLotsAndParkings() async{
   List<Marker> markersList = [];
   int markerId = 0;
    QuerySnapshot subDocuments = await parkingDocReference.collection("lots").get();
    List<DocumentSnapshot> subDocumentsSnapshots = subDocuments.documents;
    for (DocumentSnapshot subDoc in subDocumentsSnapshots){
         String subDocId = subDoc.documentID;
         DocumentSnapshot snapshot = await parkingDocReference.collection("lots")
         .document(subDocId).snapshots()
        .listen((DocumentSnapshot documentSnapshot) async {
      Map<String, dynamic> document = documentSnapshot.data();
            print(document['location'].latitude);
            markersList.add(
              Marker(
                  markerId:MarkerId(markerId.toString()),
                  position: LatLng(document['location'].latitude,
                      document['location'].longitude),
                  onTap: () => _changeMap(LatLng(
                     document['location'].latitude,
                      document['location'].longitude)),
                  icon: document['status'] == true ? customOccupiedLotIcon : customFreeLotIcon ),
            );
            markerId  ;   
}   
     }
}
return Future.value(markersList);

}


 createCustomImageForParkingsMarkers(context){
    if (customFreeLotIcon == null) {
      ImageConfiguration configuration = createLocalImageConfiguration(context);
      BitmapDescriptor.fromAssetImage(configuration, 'assets/freeLots.png')
          .then((icon) {
        setState(() {
          customFreeLotIcon = icon;
        });
      });
    }
    else if (customOccupiedLotIcon == null) {
      ImageConfiguration configuration = createLocalImageConfiguration(context);
      BitmapDescriptor.fromAssetImage(configuration, 'assets/occupiedLots.png')
          .then((icon) {
        setState(() {
          customOccupiedLotIcon = icon;
        });
      });
    }
  }
  

Добавить Setstate() сюда:

 setState(() {
      markersList.add(
        Marker(
            markerId:MarkerId(markerId.toString()),
            position: LatLng(document['location'].latitude,
                document['location'].longitude),
            onTap: () => _changeMap(LatLng(
                document['location'].latitude,
                document['location'].longitude)),
            icon: document['status'] == true ? customOccupiedLotIcon : customFreeLotIcon ),
      );
      markerId  ;
    });
  

Комментарии:

1. Привет @Amon Chowdhury! В этой строке code DocumentSnapshot snapshot = ожидает parkingDocReference.collection(«lots»).document(subDocId).snapshot().listen((DocumentSnapshot documentSnapshot) async { code Я получаю эту ошибку: значение типа ‘StreamSubscription<DocumentSnapshot>’ не может быть присвоено переменной типа ‘DocumentSnapshot’. Попробуйте изменить тип переменной или привести правый тип к «DocumentSnapshot». snipboard.io/k37wQP.jpg

2. Я попытался изменить это в: StreamSubscription<DocumentSnapshot> snapshot = ожидание parkingDocReference.collection(«lots»).document(subDocId).snapshot ().listen((DocumentSnapshot documentSnapshot) асинхронно { но контакты не будут обновляться

3. используйте setsate внутри прослушивателя

4. Не могли бы вы рассказать мне, как это сделать? Я новичок в dart и flutter:(

5. Большое вам спасибо! Теперь я понимаю, что вы имели в виду, говоря использовать setstate внутри слушателя!