Dart API调用后有状态小部件上的颤振计时问题

Dart API调用后有状态小部件上的颤振计时问题,dart,flutter,Dart,Flutter,我遇到了计时问题,我从api获取数据,然后从JSON创建列表。我想在我的listview中使用结果列表的长度作为项目计数。但是,它会在itemcount上抛出null错误,然后完成处理并显示listview。我试图找出时间问题在哪里,以及如何处理项目和小部件,以便避免错误。如果有人知道我的代码哪里有缺陷,我的代码在下面 class Specialty extends StatefulWidget { Specialty({Key key, this.title}) : super(key:

我遇到了计时问题,我从api获取数据,然后从JSON创建列表。我想在我的listview中使用结果列表的长度作为项目计数。但是,它会在itemcount上抛出null错误,然后完成处理并显示listview。我试图找出时间问题在哪里,以及如何处理项目和小部件,以便避免错误。如果有人知道我的代码哪里有缺陷,我的代码在下面

class Specialty extends StatefulWidget {
  Specialty({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _SpecialtyState createState() => new _SpecialtyState();
}

class _SpecialtyState extends State<Specialty> {

  bool _dataReceived = false;
  bool _authenticated = false;
  SharedPreferences prefs;
  List mylist;


  @override
  void initState() {
    super.initState();

    _getPrefs();
    _getSpecialty();
  }


  _getPrefs() async {
    prefs = await SharedPreferences.getInstance();
    _authenticated = prefs.getBool('authenticated');
    print('AUTH2: ' + _authenticated.toString());
    print('AUTHCODE2: ' + prefs.getString('authcode'));

  }

  _getSpecialty() async {
    var _url = 'http://$baseurl:8080/support/specialty';

    var http = createHttpClient();
    var response = await http.get(_url);

    var specialties = jsonCodec.decode(response.body);

    mylist = specialties.toList();
    //_dataReceived = true;


    setState(() {
      _dataReceived = true;
    });
  }

  Future<Null> _onRefresh() {
    Completer<Null> completer = new Completer<Null>();
    Timer timer = new Timer(new Duration(seconds: 3), () {
      completer.complete();
    });
    return completer.future;
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new RefreshIndicator(
          child: new ListView.builder(
            itemBuilder: _itemBuilder,
            itemCount: mylist.length,
          ),
          onRefresh: _onRefresh,

        ));
  }

  Widget _itemBuilder(BuildContext context, int index) {
    Specialties spec = getSpec(index);
    return new SpecialtyWidget(spec: spec,);
  }

  Specialties getSpec(int index) {
    return new Specialties(
        mylist[index]['id'], mylist[index]['name'], mylist[index]['details'],
        new Photo('lib/images/' + mylist[index]['image'], mylist[index]['name'],
            mylist[index]['name']));
    //return new Specialties.fromMap(mylist[index]);

  }


  var jsonCodec = const JsonCodec();


}
类专业扩展StatefulWidget{
专业({Key-Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_SpecialyState createState()=>new_SpecialyState();
}
类_specialystate扩展状态{
bool_dataReceived=false;
bool _authenticated=false;
共享引用优先权;
列出我的清单;
@凌驾
void initState(){
super.initState();
_getPrefs();
_GetSpeciality();
}
_getPrefs()异步{
prefs=等待SharedReferences.getInstance();
_authenticated=prefs.getBool('authenticated');
打印('AUTH2:'+_authenticated.toString());
打印('AUTHCODE2:'+prefs.getString('authcode');
}
_getSpeciality()异步{
var_url='http://$baseurl:8080/support/speciality';
var http=createHttpClient();
var response=wait http.get(_url);
var=jsoncode.decode(response.body);
mylist=Specialities.toList();
//_dataReceived=true;
设置状态(){
_dataReceived=true;
});
}
未来(更新){
Completer Completer=新的Completer();
计时器计时器=新计时器(新持续时间(秒:3),(){
completer.complete();
});
返回completer.future;
}
@凌驾
小部件构建(构建上下文){
归还新脚手架(
正文:新的刷新指示器(
子项:新建ListView.builder(
itemBuilder:\u itemBuilder,
itemCount:mylist.length,
),
onRefresh:\u onRefresh,
));
}
Widget\u itemBuilder(构建上下文,int索引){
专业规范=getSpec(索引);
返回新的SpecialtyWidget(spec:spec,);
}
专业getSpec(int索引){
返回新专业(
mylist[index][id'],mylist[index][name'],mylist[index][details'],
新照片('lib/images/'+mylist[index]['image'],mylist[index]['name'],
mylist[索引]['name']);
//返回新的专业。fromMap(mylist[index]);
}
var jsonCodec=const jsonCodec();
}

调用
异步
方法时,应使用
wait
。您可以将
initState
标记为
async
,它仍将覆盖

无论何时更改成员变量,请确保调用
setState()

如果在异步等待后执行此操作,请在
setState
之前选中
if(mounted)
,因为小部件可能不再可见


在进行异步编程时,请考虑使用而不是
setState

您应该看看FuturBuilder,它就是为此而设计的。