Flutter页面跳转时出现RangeError(index):有效范围为空的解决方法
问题原因
你遇到的RangeError (index): Invalid value: Valid value range is empty: 1错误,核心原因是页面渲染时API数据还未加载完成,surveyQuestions是空列表,但你直接通过索引1访问空列表元素。
具体细节:
- 页面初始化阶段,
build方法会优先执行,此时Provider.of<QuestionFetch>(context).questions还未拿到API返回的数据,处于空状态。 - 你定义的
widget.index初始值为1,空列表没有任何有效索引,直接访问surveyQuestions[1]必然触发索引越界错误。 - 就算数据加载完成,列表索引从
0开始,初始值设为1也可能在数据条数不足时触发同样的错误。
解决方案
1. 给surveyQuestions添加空状态判断
在build方法里先检查列表是否为空,为空时显示加载占位(或其他提示),避免直接访问索引。
2. 修正初始索引为0
因为列表索引从0开始,把SurveyScreen里的index初始值改为0。
修改后的完整代码
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import '../providers/question_fetch.dart'; import 'package:provider.dart'; import '../widgets/choice_buttons.dart'; import '../widgets/asked_questions.dart'; class SurveyScreen extends StatefulWidget { int index = 0; // 修正初始索引为0 static String route = '/survey'; SurveyScreen({super.key}); @override State<SurveyScreen> createState() => _SurveyScreenState(); } class _SurveyScreenState extends State<SurveyScreen> { @override void initState() { Future.delayed(Duration.zero).then((value) async { showDialog( context: context, builder: (context) { return const Scaffold( backgroundColor: Colors.transparent, body: Center( child: CircularProgressIndicator( color: Colors.red, backgroundColor: Colors.white, ))); }, ); await Provider.of<QuestionFetch>(context, listen: false) .fetchAndSetQuestions() .then((_) => Navigator.of(context).pop()); }); super.initState(); } @override Widget build(BuildContext context) { var surveyQuestions = Provider.of<QuestionFetch>(context).questions; return Scaffold( appBar: AppBar( centerTitle: true, elevation: 0, leading: IconButton( onPressed: () { Navigator.of(context).pop(); }, icon: Icon( Icons.arrow_back, color: Theme.of(context).primaryColor, )), backgroundColor: Theme.of(context).canvasColor, title: Text( 'Survey', style: TextStyle(color: Theme.of(context).primaryColor), ), ), body: Column( children: [ const AskedQuestions(), // 添加空状态判断 surveyQuestions.isEmpty ? const Center(child: Text("加载中...")) // 可替换为其他占位组件 : ChoiceButtons( possibleAnswers: surveyQuestions[widget.index].possibleAnswers, idQuestion: surveyQuestions[widget.index].id), ], )); } }
额外优化建议
- 给
ChoiceButtons添加索引越界二次判断,比如当widget.index >= surveyQuestions.length时,显示“无更多问题”的提示,避免后续切换索引时再次报错。 - 考虑把
index放到QuestionFetchProvider里管理,更符合状态管理逻辑,避免在Widget中维护状态导致的不一致。
内容的提问来源于stack exchange,提问作者Farid Ahmadov
相关产品推荐
相关产品推荐

