Flutter使用FutureBuilder请求API数据时出现类型不匹配报错
问题报错
_TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List')
问题根因
代码存在3处类型不匹配问题,直接触发报错:
- 核心触发点:接口返回的顶层JSON是
Map<String, dynamic>结构(properties字段才是存房产数据的列表),原代码直接把这个顶层Map传给了预期接收List类型的组件,导致Map无法被识别为List fetcharea()方法声明返回值为Future<void>,实际返回了解码后的原始JSON对象,返回值类型和实际返回值完全不匹配VerticalCards组件入参声明为List<Areaview>,内部还把列表元素强转为String,但实际需要传入的是解析后的List<Property>,列表元素是Property对象而非字符串
修复步骤
1. 修改HTTP请求方法
调整fetcharea返回值类型,直接返回解析完成的Property列表,不要返回原始解码的Map对象:
List<Property>? areaview; // 明确返回值类型为Future<List<Property>> Future<List<Property>> fetcharea() async { final response = await http.get( Uri.parse('https://arz-e-nafees.nafeessolutions.com/public/api/view')); if (response.statusCode == 200) { var jsonRes = json.decode(response.body); Areaview viewarea = Areaview.fromJson(jsonRes); areaview = viewarea.properties; // 直接返回解析好的房产列表 return viewarea.properties; } else { throw Exception('Unexpected error occured!'); } }
2. 修正VerticalCards组件的类型声明和取值逻辑
把入参类型改为List<Property>,内部直接访问Property对象的属性,不要做错误的强转:
// ignore_for_file: prefer_const_constructors, must_be_immutable, use_key_in_widget_constructors, sized_box_for_whitespace import 'package:arzenafees/Components/Constants.dart'; import 'package:arzenafees/model/areaview.dart'; import 'package:arzenafees/services/areaviewapi.dart'; import 'package:flutter/material.dart'; class VerticalCards extends StatelessWidget { // 修正入参类型为List<Property> final List<Property> areaData; VerticalCards(this.areaData); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration(color: Constants.colorSecond), height: MediaQuery.of(context).size.height, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: areaData.length, itemBuilder: (context, index) { // 直接获取当前索引的Property对象,不要强转为String final Property currentItem = areaData[index]; final String? image = currentItem.propertyImage; return Container( child: Padding( padding: const EdgeInsets.all(12.0), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0), ), child: SizedBox( width: 300, height: 180, child: GestureDetector( onTap: () {}, child: Stack(alignment: Alignment.bottomLeft, children: [ Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(15.0)), image: DecorationImage( // 增加空判断,避免图片地址为空时崩溃,可替换为项目内的占位图 image: image != null ? NetworkImage(image) : const AssetImage('assets/placeholder.png') as ImageProvider, fit: BoxFit.fill, ), ), ), // 可自行扩展添加标题、价格、地址等其他Property字段的展示逻辑 ]), )), ), )); }, ), ); } }
3. 给FutureBuilder添加明确泛型
补全加载、错误、空数据的状态判断,避免类型推断出错:
// 明确指定FutureBuilder的泛型为List<Property> FutureBuilder<List<Property>>( future: fetcharea(), builder: (context, AsyncSnapshot<List<Property>> snapshot) { // 加载中状态 if (snapshot.connectionState != ConnectionState.done) { return const Center(child: CircularProgressIndicator()); } // 加载错误状态 if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } // 空数据状态 if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Center(child: Text('暂无数据')); } // 正常返回数据 return VerticalCards(snapshot.data!); }, ),
内容的提问来源于stack exchange,提问作者Ali Punjabi
相关产品推荐
相关产品推荐

