当我尝试调用 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 调用工作正常
答案 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(...)
如果任何字段为空,我需要使用 ?.
运算符