【问题标题】:infinite loading for json data in flutter在颤动中无限加载json数据
【发布时间】:2021-02-17 21:38:48
【问题描述】:

编辑-“当我尝试运行 print(snapshot.error) 时,它给出了“int 类型不是字符串类型的子类型””

我正在尝试从https://raw.githubusercontent.com/RahulBagdiOfficial/rto_app_flutter/master/assets/json/applyonline.json获取json数据

使用https请求包解析成json数据,

我正在使用它来使用 ListView.builder 构建一个列表 如果数据为空,则返回 CircularProgressIndicator 如果它包含数据返回列表

问题是这样的

加载时卡住了

这是我的代码

class ApplyOnline extends StatefulWidget {
  @override
  _ApplyOnlineState createState() => _ApplyOnlineState();
}

class _ApplyOnlineState extends State<ApplyOnline> {
  @override
  Future<List<ApplyOnlineList>> _getapplyonlinelist() async {
    var data = await http.get(
        "https://raw.githubusercontent.com/RahulBagdiOfficial/rto_app_flutter/master/assets/json/applyonline.json");
    var jsonData = json.decode(data.body);

    List<ApplyOnlineList> applyonlinelist = [];
    for (var i in jsonData) {
      ApplyOnlineList applyonlineobject =
          ApplyOnlineList(i['index'], i['string'], i['url']);
      applyonlinelist.add(applyonlineobject);
    }
    print(applyonlinelist.length);
    return applyonlinelist;
  }

  Widget customURLButton(String text, String URL, Icon icon) {
    ;
  }

  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xff655ee6),
      appBar: AppBar(
        backgroundColor: Color(0xff655ee6),
        title: Text("Apply Online"),
      ),
      body: SingleChildScrollView(
        child: SizedBox(
          height: MediaQuery.of(context).size.height,
          child: FutureBuilder(
            future: _getapplyonlinelist(),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.data == null) {
                return Container(
                  child: Center(
                    child: CircularProgressIndicator(),
                  ),
                );
              } if(snapshot.hasData) {
                return ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (BuildContext context, int index) {
                    return ListTile(
                      title: Text(snapshot.data[index].string),
                    );
                  },
                );
              }
            },
          ),
        ),
      ),
    );
  }
}

class ApplyOnlineList {
  final int index;
  final String url;
  final String string;

  ApplyOnlineList(this.url, this.index, this.string);
}


【问题讨论】:

  • 随问题附上日志会很有帮助
  • 您好,您确定调用了 _getapplyonlinelist() 的这个函数吗?从我看到它没有被调用,这就是为什么你只有空,尝试将它放在return Scaffold() 之前并尝试打印出来

标签: json database flutter null


【解决方案1】:

您应该传递未来的参考,因为您将来不接受任何参数:

future: _getapplyonlinelist

在进入快照之前检查所有连接状态。

为了检查快照,你可以这样做:

if(snapshot.hasData) {
// return something
} else if(snapshot.hasError) {
// play with error
}
return CircularProgressIndicator();

【讨论】:

  • 你试过了吗?它应该会给你一个语法错误。
  • 阅读您的回答后,我添加了 print snapshot.error。我得到类型“int”不是“String”类型的子类型。
【解决方案2】:

问题是,您正在检查 null 并返回小部件,这样做不允许 FutureBuilder 重建,因为您没有检查其连接状态,因此数据状态不会更新。试试这个吧。

 ...
         FutureBuilder(
            future: _getapplyonlinelist(),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting || !snapshot.hasData) 
              {
                return Center(
                    child: CircularProgressIndicator(),
                );
              }
                return ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (BuildContext context, int index) {
                    return ListTile(
                      title: Text(snapshot.data[index].string),
                    );
                );
              }
...

检查ConnectionState 将使future builder 正确解决future。

【讨论】:

  • 检查状态与 FutureBuilder 解决未来有什么关系?
  • 检查 ConnectionState 可确保您等到未来完成。如果您改为将数据与 null 进行比较并呈现它,构建器将构建它并且数据将为 null
【解决方案3】:
future: _getapplyonlinelist(),

不要这样做。这样,每次调用 build 函数时,您的 Future 都会重新开始。您需要启动它一次然后等待它。

在您的状态下,在构建方法之外,有一个变量来保存未来。将_getapplyonlinelist() 分配给此变量一次,可能在void initState () 方法中。然后在您的 build 方法中使用该变量。这样,无论 build 方法被调用的频率如何,它都不会一遍又一遍地启动 Future。

在你的状态类中:

Future<List<ApplyOnlineList>> waitingForOnlineList;

void initState () {
  waitingForOnlineList = _getapplyonlinelist();
}

...然后在您的build 方法中:

future: waitingForOnlineList,

【讨论】:

    猜你喜欢
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多