Обновите значки пользовательских маркеров в зависимости от переменной в Flutter - PullRequest
0 голосов
/ 14 января 2020

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

Map with custom markers

Пока мне удалось:

  • показать карту по месту нахождения пользователя
  • Установить маркеры для всех датчиков
  • Изменить значок маркера на значок custsom
  • Добавить диалоговое окно, содержащее данные датчика, для каждый маркер

Что мне нужно:

  • Использование разных значков для маркеров в зависимости от данных датчика

Так я отображаю маркеры на карта:

@override
     Widget build(BuildContext context) {    

      var userLocation = Provider.of<UserLocation>(context );

      Set<Marker> markers = Set();           


   //this cycle creates markers with sensor's data
      for(var i=0;   i < sensors.length ; i++){
       var tempF=(strSensors[i]["temp_f"]).toString();
       double pm2_5= double.parse(strSensors[i]["PM2_5Value"]);     

       //It returns a tuple wit Aqi value(item1) and description(item2). Depending on item1 value the marker's icon should change.  
       var Aqi=AqiCalculation().AqiValue(pm2_5);


      //my attempt to update teh value of the asset's path depending on Aqi.item1 value 
       setState((){
         marcador=updateCustomMapPin(Aqi.item1); 
       });       


        Marker resultMarker = Marker(

        markerId: MarkerId(strSensors[i]["ID"].toString()),     
        position: LatLng(strSensors[i]["Lat"].toDouble(),strSensors[i]["Lon"].toDouble()),
        icon: BitmapDescriptor.fromBytes(markerIcon),
        onTap: (){  

          //shows an image in diaolog box depending on Aqi value
                   if(Aqi.item1 > 80){
                     image="https://i.gifer.com/72fB.gif";               
                   }
                   else{
                     image= "https://raw.githubusercontent.com/Shashank02051997/FancyGifDialog-Android/master/GIF's/gif14.gif";
                   }                                    


        String tempC;
                   tempC=((int.parse(tempF)-32)/1.8).toStringAsPrecision(4);                   

                                showDialog<void>(                                   
                       context: context,
                       builder: (_) => NetworkGiffyDialog(
                               key: keys[1],                            
                               image: Image.network(
                                 image,
                                 fit: BoxFit.cover,                              
                                // alignment:Alignment.bottomLeft,
                               ),
                               entryAnimation: EntryAnimation.TOP_LEFT,
                               title: Text('Sensor: ${strSensors[i]["Label"]}'
                               ,
                                 textAlign: TextAlign.center,
                                 style: TextStyle(
                                     fontSize: 22.0, fontWeight: FontWeight.bold),
                               ),
                               description: Text(
                                 'PM2.5: $pm2_5 Temp:${tempC}° Aqi:${Aqi.item1} Status:${Aqi.item2}',
                                 textAlign: TextAlign.center,
                                 style: TextStyle(
                                     fontSize: 22.0, fontWeight: FontWeight.normal),

                               ),

                               onlyOkButton: true,
                               onOkButtonPressed: (){
                                 Navigator.pop(context);//closes dialogbox
                               },                                   
                             )
                    );          

        }
       );
   // Add it to Set
       markers.add(resultMarker);
       }  

Чтобы изменить значок маркера по умолчанию, я сделал это:

  @override
     void initState(){
       super.initState();
       setCustomMappin('android/assets/Cloudgray.png');
        }

    //Converts image to Unint8List
         Future<Uint8List> getBytesFromAsset(String path, int width) async {
      ByteData data = await rootBundle.load(path);
      ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width);
      ui.FrameInfo fi = await codec.getNextFrame();
      return (await fi.image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List();
    }



     void setCustomMappin(marker)async {

       markerIcon = await getBytesFromAsset(marker, 150);
     }

Это изменит все значки на актив моего значка по умолчанию. Я попытался динамически обновить путь ресурса, передав его в l oop, который создает все маркеры:

setState((){
             marcador=updateCustomMapPin(Aqi.item1); 
           }); 

, который использует эту функцию:

    //returns icon path depending on the value
     updateCustomMapPin(value)  {

      String marker='';

           if(value<=50){
            marker = 'android/assets/Cloudgreen.png';
           }
           else if(value>50  && value<=100){
             marker='android/assets/Cloudyellow.png';
           }
           else if(value>100  && value<=150){
             marker='android/assets/CloudOrange.png';
           }
           else if(value>150  && value<=200){
             marker='android/assets/Cloudred.png';


 }
       else if(value>200  && value<=300){
         marker='android/assets/Cloudpurple.png';
       }
       else{
       marker='android/assets/Cloudtoxic.png';
       }

       return marker;

     }

И это где Я застрял, значок маркера не меняется, несмотря на это, в тот момент, когда каждый маркер создается, отображается соответствующий значок.

Может быть, это проблема с пониманием жизненного цикла приложения Flutter, Я надеюсь, что вы можете мне помочь.

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 27 января 2020

Я решаю эту проблему, устанавливая все пользовательские контакты в методе initState, проблема возникла из-за того, что преобразование изображений в байты является асинхронным c процессом и из-за способа установки динамического c выбора Маркеры не было достаточно времени, чтобы сделать это преобразование. Поэтому я установил метод, который преобразовывал каждое изображение в байты в initState, передавал эти значения глобальным переменным и затем использовал их в условных выражениях для каждого случая.

0 голосов
/ 14 января 2020

Извините, я не могу использовать комментарий.

Что произойдет, если вы добавите логин в setState?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...