如何解决Flutter中RangeError (index): Invalid value: Only valid value is 0: 1报错
错误原因
- Dart语言的
List是0索引结构,也就是列表第一个元素的下标是0,第二个是1,以此类推,最大有效下标永远是列表长度减1 - 你的代码中调用
cardslist方法时传入的下标是1/2/3/4,访问name[index]/id[index]时,下标超出了列表的有效范围,就触发了RangeError。 - 报错后恢复正常是因为错误触发后Flutter会触发组件重建,此时列表已经新增了对应数量的控制器,下标刚好合法,但这个逻辑非常不稳定。
修复步骤
- 访问控制器列表时将传入的下标减1,匹配列表的0索引规则
- 调整计数变量初始值为1,匹配首屏仅显示1张卡片的需求
- 补充
dispose生命周期方法,销毁所有TextEditingController避免内存泄漏 - 优化卡片生成逻辑,无需单独维护4个可见性变量,代码更简洁易维护
修正后完整代码
import 'package:flutter/material.dart'; void main() { runApp(App()); } class App extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: CardWithTextformfield(), ); } } class CardWithTextformfield extends StatefulWidget { const CardWithTextformfield({Key? key}) : super(key: key); @override _CardWithTextformfieldState createState() => _CardWithTextformfieldState(); } class _CardWithTextformfieldState extends State<CardWithTextformfield> { var name = <TextEditingController>[]; var id = <TextEditingController>[]; // 初始显示1张卡片 var cardCount = 1; // 最多4张卡片 final maxCardCount = 4; void incrementcard(){ setState(() { if(cardCount < maxCardCount){ cardCount++; } }); } @override void dispose() { // 销毁所有控制器避免内存泄漏 for (var controller in name) { controller.dispose(); } for (var controller in id) { controller.dispose(); } super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Card with TextformField'), ), floatingActionButton: FloatingActionButton( onPressed: cardCount >= maxCardCount ? null : incrementcard, child: const Icon(Icons.add), ), body: Container( child: SingleChildScrollView( child: Column( // 动态生成对应数量的卡片 children: List.generate(cardCount, (index) => cardslist(index + 1)), ), ), ), ); } Widget cardslist(int index){ // 转换为0索引匹配列表规则 int listIndex = index - 1; if(name.length <= listIndex){ name.add(TextEditingController()); id.add(TextEditingController()); } return Card( margin: const EdgeInsets.all(10), child: Container( child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( margin: const EdgeInsets.all(10), child: const Text('Team Name: ')), Expanded(child: TextFormField( controller: name[listIndex], decoration: const InputDecoration(hintText: 'Team Name'), ),), Container( margin: const EdgeInsets.all(10), child: const Text('Team Id: '),), Expanded(child: TextFormField( controller: id[listIndex], decoration: const InputDecoration(hintText: 'Team Id'), ),), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( child: Container( width: 50,height: 50, margin: const EdgeInsets.all(10), decoration: BoxDecoration( shape: BoxShape.rectangle, color:Colors.grey, ), child: const Center(child: Text('IT'),), ), ), GestureDetector( child: Container( width: 50,height: 50, margin: const EdgeInsets.all(10), decoration: BoxDecoration( shape: BoxShape.rectangle, color: Colors.grey, ), child: const Center(child: Text('DEV'),), ), ), GestureDetector( child: Container( width: 50,height: 50, margin: const EdgeInsets.all(10), decoration: BoxDecoration( shape: BoxShape.rectangle, color: Colors.grey, ), child: const Center(child: Text('TEST'),), ), ), GestureDetector( child: Container( width: 50,height: 50, margin: const EdgeInsets.all(10), decoration: BoxDecoration( shape: BoxShape.rectangle, color: Colors.grey, ), child: const Center(child: Text('HR'),), ), ), ], ) ], ), ), ); } }
内容的提问来源于stack exchange,提问作者Shanmukha
相关产品推荐
相关产品推荐

