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

Flutter开发ToDo应用时ListView读取字符串列表报索引越界错误

Flutter ToDo应用索引越界问题修复

错误原因

  • 误用自定义_counter作为列表索引
    ListView.builder的itemBuilder回调会自动传入当前渲染项的下标参数,你全程用固定的_counter取值,当_counter数值等于_taskItems长度时,就会触发索引越界(Dart列表下标从0开始,长度为n的列表最大合法下标是n-1)
  • _counter变量完全多余
    列表的元素数量可以直接通过_taskItems.length获取,不需要额外维护变量统计

修复方案

按以下步骤修改代码即可:

  1. 删除_counter变量的定义、自增操作相关代码
  2. 修改_buildTaskList方法,使用itemBuilder自带的索引参数取值
  3. 补充空输入校验,避免添加空任务

修复后完整代码:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ToDo List',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyTaskList(),
    );
  }
}

class MyTaskList extends StatefulWidget {
  @override
  _MyTaskListState createState() => _MyTaskListState();
}

class _MyTaskListState extends State<MyTaskList> {
  final _taskItems = <String>[];
  final myController = TextEditingController();

  @override
  void dispose(){
    myController.dispose();
    super.dispose();
  }

  void _addTask(String task){
    // 空输入校验
    if(task.trim().isEmpty) return;
    setState(() {
      _taskItems.add(task);
    });
    myController.clear();
  }

  Widget _buildTaskList() {
    return ListView.builder(
        itemCount: _taskItems.length,
        // 这里第二个参数index就是当前项的下标
        itemBuilder: (BuildContext context, index) {
          return _buildTask(_taskItems[index]);
        }
    );
  }

  Widget _buildTask(String task) {
    return ListTile(
      title: Text(task),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ToDo List"),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => showDialog<String>(
            context: context,
            builder: (context) => AlertDialog(
              title: Text("New Task"),
              content: TextField(
                controller: myController,
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: "Enter New Task",
                ),
              ),
              actions: <Widget>[
                TextButton(
                    onPressed: () => {
                      _addTask(myController.text),
                      Navigator.pop(context, "ok"),
                    },
                    child: const Text("OK")),
              ],
            )
        ),
        child: Icon(Icons.add),
      ),
      body: _buildTaskList(),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 15:24:01