Flutter listView构建器不断给出此错误:“ RangeError(索引):无效值:不在0..19范围内(包括20)”

时间:2019-05-12 00:18:08

标签: listview flutter

我有此新闻ApI,该新闻获得了最新的新闻更新,但是即使我有一个长度为“ itemCount”的项目,我的列表视图也给我一个错误。

我在Itemcount上尝试了“ _total.length”,但它给了我一个错误..提示“未为类'int'定义getter'length'。

尝试导入定义“ length”的库,将其名称更正为现有吸气剂的名称,或者定义一个名为“ length”的吸气剂或字段。”

class _NewsUpdateState extends State<NewsUpdate> {

  List _bottomItems = 
   [
    {"icon": FontAwesomeIcons.fire, "index": 0},
    {"icon": FontAwesomeIcons.moneyBillAlt, "index": 1},
    {"icon": FontAwesomeIcons.bell, "index": 2},
    {"icon": FontAwesomeIcons.futbol, "index": 3},
  ];

  String _apiKey = '46d80623786da4a97847da2b6cd7747';

  int _currentTab = 0;
  String _apiUrl = '';
  int _total = 0;
  List _articles = [];
  bool _loading = true;

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

    changeTab(index: 0);
  }

  void changeTab({int index = 0}) {
    //tab1 is about top-headlines
    //tab2 is about bitcoins
    //tab3 = apple
    //tab4 = techcrunch

    switch (index) {
      case 0:
        _apiUrl =
            'https://newsapi.org/v2/top-headlines?country=za&apiKey=' +
                _apiKey;
        break;
      case 1:
        _apiUrl =
            'https://newsapi.org/v2/top-headlines?country=za&category=business&apiKey=' +
                _apiKey;
        break;
      case 2:
        _apiUrl =
            'https://newsapi.org/v2/top-headlines?country=za&category=entertainment&apiKey=' +
                _apiKey;
        break;
      case 3:
        _apiUrl =
            'https://newsapi.org/v2/top-headlines?country=za&category=sports&apiKey=' +
                _apiKey;
        break;
    }

    print(_apiUrl);

    setState(() {
      _loading = true;
      _total = 0;
      _articles = [];
    });

    http.get(_apiUrl).then((response) {
      var data = json.decode(response.body);
      setState(() {
        _total = data['totalResults'];
        _articles = data['articles'];
        _loading = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          "Latest News",
          style: TextStyle(
              color: Colors.black, fontSize: 25.0, fontWeight: FontWeight.bold),
        ),
        elevation: 5.0,
        backgroundColor: Colors.white,
        centerTitle: true,
      ),
      bottomNavigationBar: _buildBottomNavigation(context),
      body: new SafeArea(child: _buildBody(context)),
    );
  }

  _buildBottomNavigation(BuildContext context) {
    var _items = <BottomNavigationBarItem>[];

    for (var item in _bottomItems) {
      _items.add(new BottomNavigationBarItem(
        icon: new Icon(
          item['icon'],
          color: Colors.black,
        ),
        title: new Text(''),
      ));
    }

    return new BottomAppBar(
      color: Colors.white,
      child: new Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: _bottomItems.map((x) {
          return new IconButton(
            icon: new Icon(
              x['icon'],
              color: _currentTab == x['index'] ? Colors.black : Colors.black38,
            ),
            onPressed: () {
              setState(() {
                _currentTab = x['index'];
              });
              changeTab(index: x['index']);
            },
          );
        }).toList(),
      ),
    );
  }

  _buildBody(BuildContext context) {
    if (_loading) {
      return new SpinKitCircle(
        color: Colors.black,
        size: 50.0,
      );
    }

    print(_articles);

    return new ListView.builder(
      itemBuilder: (context, int index) {
        return new Padding(
          padding: new EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
          child: new ListItem(data: _articles[index]),
        );
      },
      itemCount: _total,
    );
  }
}

这应该将api的总结果的实际长度设置为itemcount

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题:

您还必须传递itemCount参数

child: ListView.builder(
    itemCount: list.length,
    itemBuilder: (context, index) {
        return Text(list[index].description);
    }),

答案 1 :(得分:0)

“ totalResults”的数量大于请求中实际获得的文章数量,因此您的setState应该如下所示:

setState(() {
        _total = data['articles'].length;
        _articles = data['articles'];
        _loading = false;
      });

您可以使用pagepageSize参数从api获取更多文章。看看他们在https://newsapi.org/docs/endpoints/top-headlines上的文献资料。