Flutter: setState внутри сборки - PullRequest
0 голосов
/ 09 июля 2020

Я хочу получить данные из Inte rnet, поэтому я использую функцию с именем getNumData и помещаю ее в функцию Build. Функция getNumData использует http.get для извлечения данных, а затем сохраняет их после декодирования. Вот и проблема. Мне нужно вызвать setState для хранения данных (установить список Numdata на данные, которые я только что получил). Но если я это сделаю, это станет ошибкой «setState, вызванной во время сборки». Это неловкая ситуация. Что я могу сделать, чтобы решить эту проблему? Например, спасибо.

Функция сборки:

Widget build(BuildContext context) {

    final key = utf8.encode(AppKey);
    final hmac = hmacSha1(key, utf8.encode(SignDate));
    final base64HmacString = base64Encode(hmac);

    final Authorization = "hmac username=\"" + AppID + "\", algorithm=\"hmac-sha1\", headers=\"x-date\", signature=\"" + base64HmacString + "\"";

    getNumData();
    for(int i = 0 ; i < Numdata.length ; i++){
      if(Numdata[i]['stationName'] == DStation){
        DStationNum = Numdata[i]['stationCode'];
        break;
      }
    }
    for(int i = 0 ; i < Numdata.length ; i++){
      if(Numdata[i]['stationName'] == AStation){
        AStationNum = Numdata[i]['stationCode'];
        break;
      }
    }



    return Scaffold(
      appBar: AppBar(
        backgroundColor: Color.fromRGBO(191, 62, 255, 1),
        title: Text('火車查詢'),
      ),
      body: FutureBuilder(
          future: getTableData(Authorization, xdate, DStationNum, AStationNum),
          builder: (context, snap){
            if(!snap.hasData){
              return Container();
            }
            List<dynamic> datas = [];
            datas = jsonDecode(snap.data.body);
            return ListView.builder(
              itemCount: datas.length,
              itemBuilder: (context, index){
                return ListTile(title: Text(datas[index]['DailyTrainInfo']["TrainTypeName"]["Zh_tw"] + '      ' + datas[index]['OriginStopTime']["DepartureTime"] + '   =>   ' + datas[index]['DestinationStopTime']["DepartureTime"]), subtitle: Text(datas[index]['DailyTrainInfo']["TrainNo"]),);
              },
            );
          }),
      bottomNavigationBar: BottomNavigationBar(
        onTap: onTabTapped,
        currentIndex: _currentIndex, // this will be set when a new tab is tapped
        items: [
          new BottomNavigationBarItem(
            icon: new Icon(Icons.school),
            title: new Text('大學'),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(Icons.directions_subway),
            title: new Text('交通'),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(Icons.person),
            title: new Text('個人'),
          )
        ],
      ),
    );
  }

Функция getNumData:

getNumData() async{
    final String hostNum = 'http://ods.railway.gov.tw/tra-ods-web/ods/download/dataResource/0518b833e8964d53bfea3f7691aea0ee';
    final response = await http.get(hostNum);
    setState(() {
      Numdata = jsonDecode(utf8.decode(response.bodyBytes));
    });
  }

1 Ответ

0 голосов
/ 09 июля 2020

Способом решения этой проблемы может быть перемещение всего этого c

getNumData();
for(int i = 0 ; i < Numdata.length ; i++){
  if(Numdata[i]['stationName'] == DStation){
    DStationNum = Numdata[i]['stationCode'];
    break;
  }
}
for(int i = 0 ; i < Numdata.length ; i++){
  if(Numdata[i]['stationName'] == AStation){
    AStationNum = Numdata[i]['stationCode'];
    break;
  }
}

logi внутрь getTableData. Таким образом, ваш метод getTableData будет преобразован в

//DStationNum and  AStationNum won't be passed as parameter since they will be calculated inside
Future<...> getTableData(...) async { 
    await getNumData();
    for(int i = 0 ; i < Numdata.length ; i++){
      if(Numdata[i]['stationName'] == DStation){
        DStationNum = Numdata[i]['stationCode'];
        break;
      }
    }
    for(int i = 0 ; i < Numdata.length ; i++){
      if(Numdata[i]['stationName'] == AStation){
        AStationNum = Numdata[i]['stationCode'];
        break;
      }
    }

    ....
}
...