You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:27:35