Flutter:在 null 上调用了 getter 'length'

时间:2021-02-23 16:15:07

标签: flutter dart

当我尝试调用 api 时,它被调用并到达 itemCount 中的 ListView.builder 但随后它显示这样的错误,

<块引用>

getter 'length' 被调用为 null。

class ChopperNewsCard extends StatefulWidget {
  @override
  _ChopperNewsCardState createState() => _ChopperNewsCardState();
}

class _ChopperNewsCardState extends State<ChopperNewsCard> {
  ScrollController scrollController = ScrollController();
  ApiCall apiCall = ApiCall();
  ChopperNews res = ChopperNews();
  Future<void> getResponse() async {
    res = await apiCall.getNews(5);
  }

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

    getResponse();
  }

  @override
  void dispose() {
    super.dispose();
    scrollController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    var height = MediaQuery.of(context).size.height;
    var width = MediaQuery.of(context).size.width;
    return Container(
      height: height * 0.37,
      width: double.infinity,
      child: ListView.builder(
        itemCount: res.articles.length + 1, //<--------here length getting null
        controller: scrollController,
        physics: AlwaysScrollableScrollPhysics(),
        scrollDirection: Axis.horizontal,
        shrinkWrap: true,
        itemBuilder: (context, index) {
          if (index == res.articles.length) {
            if (index == res.totalResults) {
              return null;
            } else {
              return Center(child: CircularProgressIndicator());
            }
          } else {
            return Container(
              width: width * 0.70,
              padding: EdgeInsets.only(right: width * 0.05),
              child: Card(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15),
                ),
                elevation: 3,
                child: Column(
                  children: [
                    ClipRRect(
                      borderRadius: BorderRadius.circular(15),
                      child: CachedNetworkImage(
                        imageUrl: res.articles[index].urlToImage == null
                            ? Url.noImage
                            : res.articles[index].urlToImage,
                        fit: BoxFit.cover,
                        width: double.infinity,
                        height: height * 0.2,
                        placeholder: (context, url) =>
                            Center(child: CircularProgressIndicator()),
                        errorWidget: (context, url, error) =>
                            Icon(Icons.error_outline_sharp),
                      ),
                    ),
                  
                  ],
                ),
              ),
            );
          }
        },
      ),
    );
  }
}

从我试图调用我的 api 的地方,

import 'package:chopper/chopper.dart';
import '../models/chopper_news.dart';

import 'chopper_api_service.dart';

class ApiCall {
  ChopperApiService chopperApiService;
  Future<ChopperNews> getNews(int page) async {
    chopperApiService = ChopperApiService.create();
   var apiResponse = await chopperApiService.getNews(pageSize: page);
    return apiResponse.body;
  }
}

在调试模式下,它在长度被称为 null 后显示响应,所以我认为我的 api 调用工作正常

3 个答案:

答案 0 :(得分:0)

在提供 API 响应之前,您正在调用 API 并呈现数据。

对于这种情况,您可能希望使用 FutureBuilder

或者为了测试,你可以添加一个条件来检查 articles 中的 res 是否为空,然后显示一个加载器。

当您收到回复时,请使用 setState(){} 更改值并显示您的 ListView.Builder

答案 1 :(得分:0)

原因是调用build()的时候,getResponse()没有完成。
由于这个原因,'res' 为空。

你能用 'FutureBuilder' 包裹 'ListView.builder' 吗?

答案 2 :(得分:0)

当我得到这样的响应时,我需要使用 setState() 来更新列表,

    Future<void> getResponse(int page) async {
    var data = await apiCall.getNews(page);
    setState(() {
      res = data;
    });
  }

现在检查它是否为空然后显示加载器,

   return res?.articles?.isEmpty == null 
          ? CircularProgressIndicator()
          : ListView.builder(...)

如果任何字段为空,我需要使用 ?. 运算符