Flutter问题:API获取的Future列表无法在Dropdown展示,报类型不匹配错误
解决Flutter中FutureBuilder出现'type List is not a subtype of type Future
- '错误
我需要调用API获取数据并展示在表单的Dropdown组件中,但运行时抛出错误:
type 'List' is not a subtype of type 'Future' of 'function result'
实现代码
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:sample/models/item.model.dart'; import 'package:sample/models/unit.model.dart'; import 'package:sample/services/unit.service.dart'; class ItemDialog extends Stateful Widget { Item? item; ItemDialog.add({super.key}) { item = Item(); } ItemDialog.edit(this.item, {super.key}) { item = item; } @override State<ItemDialog> createState() => _ItemDialogState(item); } class _ItemDialogState extends State<ItemDialog> { Item? item; _ItemDialogState(this.item); final _formKey = GlobalKey<FormState>(); late Future<List<Unit>> unitList; Unit? unit; AppBar _createAppBar(BuildContext context) { return AppBar( title: widget.item?.name == null ? const Text("Add new item") : Text("Edit item ${widget.item?.name}"), actions: [ ElevatedButton( child: const Text("Save"), onPressed: () { if (_formKey.currentState!.validate()) { setValueFromForm(); Navigator.of(context).pop(item); } }, ) ], ); } @override void initState() { super.initState(); setInitialValue(); } setInitialValue() { getAllData(widget.item!); } getAllData(Item item) { unitList = getAllUnits(item.house!.id); } @override Widget build(BuildContext context) { return Scaffold( appBar: _createAppBar(context), body: SingleChildScrollView( child: Center( child: Column( children: [ Padding( padding: const EdgeInsets.only(left: 10, right: 10), child: Form( key: _formKey, child: Column( children: [ FutureBuilder( future:unitList, builder: (BuildContext context, AsyncSnapshot snapshot) { return snapshot.hasData ? Container( child: DropdownButton<Unit>( hint: Text('Make a selection'), items: snapshot.data.map<DropdownMenuItem<Unit>>((item) { return DropdownMenuItem<Unit>( value: item, child: Text(item.title), ); }).toList(), onChanged: (value) { setState(() { unit = value; print(value); }); }, ), ) : Container( child: Center( child: Text('Loading...'), ), ); }, ), ], ), ), ) ], ) ) ), ); } }
API请求方法代码
Future<List<Unit>> getAllUnits(String? id) async { final response = await getDio() .get('/unit/house/$id'); if (response.statusCode == 200) { List<Unit> list = List<Unit>.from(response.data.map((item) => Unit.fromJson(item)).toList()); return list; } else { throw Exception('Failed to load data'); } }
问题原因
核心问题是unitList被声明为late Future<List<Unit>>,但通过setInitialValue和getAllData的间接赋值过程中,Dart的类型推断出现偏差——getAllData未明确返回类型,导致赋值时无法确保unitList始终持有Future<List<Unit>>类型的值,最终触发类型不匹配错误。
解决方案
1. 简化初始化逻辑,直接在initState中赋值
删除冗余的setInitialValue和getAllData方法,直接在initState中初始化unitList,避免间接调用带来的类型问题:
@override void initState() { super.initState(); unitList = getAllUnits(widget.item!.house!.id); }
2. 给FutureBuilder添加明确的类型注解
给AsyncSnapshot指定泛型类型,让Dart明确数据类型,避免推断错误:
FutureBuilder<List<Unit>>( future: unitList, builder: (BuildContext context, AsyncSnapshot<List<Unit>> snapshot) { // ... 原builder逻辑 }, )
3. 确保DropdownButton的items生成逻辑正确
添加空安全判断,避免数据为空时出现异常:
items: snapshot.data?.map<DropdownMenuItem<Unit>>((unit) { return DropdownMenuItem<Unit>( value: unit, child: Text(unit.title), ); }).toList() ?? [],
总结
通过简化初始化流程、明确泛型类型,即可解决该类型不匹配错误。同时避免在build方法中重复创建Future,确保Future只初始化一次,提升组件性能和稳定性。
内容的提问来源于stack exchange,提问作者Rohith Poyyeri
相关产品推荐
相关产品推荐

