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

Flutter中FutureBuilder搭配DropdownButton触发RangeError报错

报错原因
  • 核心触发点是你在build方法中直接访问空列表的[0]索引:uniquelist的生成逻辑依赖状态变量seen,第一次执行去重后所有品牌已经被加入seen集合,后续setState触发页面重建时,seen.add(brand)会全部返回false,最终uniquelist变成空列表,访问索引0直接抛出RangeError。
  • 选中值defaultValue是build方法内的局部变量,setState时变量会被重新赋值,既无法持久化选中状态,也会因为重建时的执行顺序问题拿到空列表的索引。
  • 数据加载、去重逻辑全部写在build流程里,且FutureBuilder的future参数没有缓存,每次页面重建都会重复触发json加载、重复往brands列表里追加数据,进一步放大异常。
  • 访问列表索引前没有做非空判断,空列表场景直接触发索引越界。
修复步骤
  • 将选中值、品牌列表全部提升为State的成员变量,不要在build方法里声明存页面状态的临时变量
  • 把json解析、数据去重逻辑抽离为单独的异步方法,在initState阶段就初始化加载任务并缓存Future,避免build重复触发资源加载
  • 去重逻辑在数据加载阶段一次性完成,不要放到每次build执行的流程里
  • 访问列表首个元素设置默认值前,先判断列表是否有数据,避免空列表索引越界
  • 选中值变化时通过setState更新状态类里的选中变量,驱动下拉框正确刷新显示
修复后完整代码
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class Features extends StatefulWidget {
  const Features({Key? key}) : super(key: key);

  @override
  State<Features> createState() => _FeaturesState();
}

class _FeaturesState extends State<Features> {
  List<String> brands = [];
  String? selectedBrand;
  late Future<void> dataLoadFuture;

  @override
  void initState() {
    super.initState();
    dataLoadFuture = loadBrandData();
  }

  Future<void> loadBrandData() async {
    final jsonString = await rootBundle.loadString('assets/phone-model.json');
    final jsonData = json.decode(jsonString) as Map;
    // 加载时直接完成去重
    final uniqueSet = <String>{};
    for (final key in jsonData.keys) {
      uniqueSet.add(key.toString());
    }
    brands = uniqueSet.toList();
    // 列表非空时初始化默认选中值
    if (brands.isNotEmpty) {
      selectedBrand = brands.first;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FutureBuilder(
          future: dataLoadFuture,
          builder: (BuildContext context, snapshot) {
            // 数据加载完成再渲染下拉组件
            if (snapshot.connectionState == ConnectionState.done) {
              if (brands.isEmpty) {
                return const Text('暂无可用品牌数据');
              }
              return DropdownButton<String>(
                value: selectedBrand,
                icon: const Icon(Icons.arrow_downward),
                elevation: 16,
                style: const TextStyle(color: Colors.deepPurple),
                underline: Container(
                  height: 2,
                  color: Colors.deepPurpleAccent,
                ),
                items: brands.map((brand) {
                  return DropdownMenuItem(
                    value: brand,
                    child: Text(brand),
                  );
                }).toList(),
                onChanged: (value) {
                  setState(() {
                    selectedBrand = value;
                  });
                },
              );
            }
            // 加载过程显示进度条
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者OraOraOra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:09:37