API调用后有状态小部件上的抖动计时问题 [英] flutter timing problems on stateful widget after API call

查看:68
本文介绍了API调用后有状态小部件上的抖动计时问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了计时问题,我从api获取数据,然后从JSON创建列表。我认为将结果列表的长度用作列表视图中的项目数。但是,它将在itemcount上引发空错误,然后完成处理并显示listview。我试图找到时间问题在哪里以及如何处理项目和小部件,以便避免错误。如果有人对我的代码有任何疑问,我的代码将显示在下面。

I am running into timing problems, I am getting data from a api, then creating a list from the JSON. I think use the length of the resulting list as the item count in my listview. However it throws a null error on the itemcount and then completes processing and presents the listview. I am trying to find where the timing problem is and how items and widgets are processed so that I can avoid the error. My code is below if anyone has any ideas where my code is flawed.

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();


}


推荐答案

调用 async 方法时,应使用 await 。您可以将 initState 标记为 async ,它仍然会覆盖。

You should use await when invoking your async methods. You can mark initState as async, it will still override.

每当对成员变量进行突变时,请确保调用 setState()

Make sure to call setState() whenever you mutate member variables.

检查 setState 之前> if(已安装),因为该小部件可能不再可见。

Check if (mounted) before setState if you are doing it after an async wait, because the widget may no longer be visible.

考虑使用 进行异步编程时,使用FutureBuilder 代替 setState

这篇关于API调用后有状态小部件上的抖动计时问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆