如何解决构建时抛出_CastError:Future<dynamic>不是类型转换中List<dynamic>的子类型
报错根因
你遇到的类型转换报错、itemCount报错都是类型推断缺失+异步方法调用逻辑错误导致的,具体问题点:
pic()是异步方法,返回值为Future类型,你在itemBuilder里直接调用pic() as List相当于把Future强转成List,必然触发类型不匹配错误- 没有给
FutureBuilder和pic()指定泛型,snapshot.data默认是dynamic类型,直接调用.length会因为无明确类型报错 Image.network的URL拼接语法错误,插值表达式被写死在字符串里无法生效initState中调用的pic()属于无效请求,FutureBuilder初始化时会自动触发传入的future方法
修复后完整代码
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'UI_Tool/size_fit.dart'; class Gallery extends StatefulWidget { @override _GalleryState createState() => _GalleryState(); } class _GalleryState extends State<Gallery> { // 明确指定方法返回类型为Future包裹的List Future<List<dynamic>> pic() async { var url = "http://120.76.247.131:8081/findAllImages"; var response = await http.get(Uri.parse(url)); return json.decode(response.body) as List; } @override void initState() { super.initState(); // 删掉无用的pic()调用,避免重复发请求 } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Gallery'), ), // 给FutureBuilder指定泛型,明确接收List类型的异步结果 body: FutureBuilder<List<dynamic>>( future: pic(), builder: (context, snapshot) { if (snapshot.hasError) print(snapshot.error); if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) { // 直接拿snapshot里已经解析好的列表,不需要再调用pic() List list = snapshot.data!; return ListView.builder( // 直接用列表长度作为itemCount itemCount: list.length, itemBuilder: (context, index) { return Card( child: ListTile( title: Container( width: 100, height: 100, // 修正URL拼接语法 child: Image.network( "http://120.76.247.131:8081/findAllImages/${list[index]["image"]}" ), ), ) ); } ); } else { return const Center( child: CircularProgressIndicator(), ); } }, ), ); } }
关键修改说明
- 给异步方法
pic()和FutureBuilder增加泛型约束,明确类型,解决itemCount调用.length报错的问题 - 直接通过
snapshot.data获取已经完成异步请求的结果,不再重复调用异步方法pic(),解决类型转换报错 - 修正图片URL的插值写法,保证图片地址可以正确拼接
- 增加
ConnectionState判断,优化加载逻辑的严谨性
内容的提问来源于stack exchange,提问作者WJLee9559
相关产品推荐
相关产品推荐

