Flutter, индекс выходит за пределы допустимого диапазона, когда я пытаюсь удалить элемент из списка - PullRequest
0 голосов
/ 26 мая 2020

Итак, у меня проблема, когда я удаляю элемент из списка, это дает мне ошибку вне допустимого диапазона и сообщает мне, что это происходит при попытке создать представление моей карты
На экране телефона:

 RangeError (index): Invalid value: Not in range 0..1, inclusive: 2 

В консоли отладки:

════════ Exception caught by widgets library ═══════════════════════════════════
The following RangeError was thrown building ListViewCard-[<'2'>](dirty, state: _ListViewCard#e102b):
RangeError (index): Invalid value: Not in range 0..1, inclusive: 2

The relevant error-causing widget was
    ListViewCard-[<'2'>] 
package:my_todo_app/main.dart:128
When the exception was thrown, this was the stack
#0      List.[]  (dart:core-patch/growable_array.dart:146:60)
#1      _ListViewCard.build 
package:my_todo_app/main.dart:64
#2      StatefulElement.build 
package:flutter/…/widgets/framework.dart:4619
#3      ComponentElement.performRebuild 
package:flutter/…/widgets/framework.dart:4502
#4      StatefulElement.performRebuild 

Я не знаю, что я сделал не так, когда я добавляю элемент, список обновляется нормально,
Вот посмотрите на мою игру:
Простой список:

List<Todo> todos = [
  Todo("Learn Flutter"),
  Todo("Make Todo App List"),
  Todo("Search for out of range error"),
];


Карточный вид для моего списка:

class ListViewCard extends StatefulWidget {
  final int index;
  final Key key;
  final List<Todo> todoList;

  ListViewCard(this.index, this.key, this.todoList);
  @override
  _ListViewCard createState() => _ListViewCard();
}


class _ListViewCard extends State<ListViewCard> {
  @override
  Widget build(BuildContext context) {
    return Card(
        child: ListTile(
        title: Text(widget.todoList[widget.index].text),
        trailing: IconButton(
         icon: Icon(Icons.delete),
          onPressed: () {
            setState(() {
              todos.removeAt(widget.index);
            });
          },
        ),
        onTap: () {},
      ),
     );
  }
}


Домашняя страница:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Todo),
      ),
      body: ReorderableListView(
        onReorder: () {},
        children: List.generate(todos.length, (index) {
          return ListViewCard(index, Key('$index'), todos);
        }),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            todos.insert(todos.length, Todo("New Todo"));
           });
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

1 Ответ

0 голосов
/ 26 мая 2020

Вы можете скопировать и вставить полный код ниже
Вы можете передать callback refresh() в ListViewCard и refresh() будет делать setState
фрагмент кода

class _MyHomePageState extends State<MyHomePage> {
...
    void refresh() {
        setState(() {});
      }

class ListViewCard extends StatefulWidget {
  final int index;
  final Key key;
  final List<Todo> todoList;
  VoidCallback callback;

  ListViewCard(this.index, this.key, this.todoList, this.callback);
...  
    onPressed: () {
                todos.removeAt(widget.index);
                widget.callback();  

рабочая демонстрация

enter image description here

полный код

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class Todo {
  String text;
  Todo(this.text);
}

List<Todo> todos = [
  Todo("Learn Flutter"),
  Todo("Make Todo App List"),
  Todo("Search for out of range error"),
];

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _onReorder(int oldIndex, int newIndex) {
    setState(
      () {
        if (newIndex > oldIndex) {
          newIndex -= 1;
        }
        final Todo item = todos.removeAt(oldIndex);
        todos.insert(newIndex, item);
      },
    );
  }

  void refresh() {
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Todo"),
      ),
      body: ReorderableListView(
        onReorder: _onReorder,
        children: List.generate(todos.length, (index) {
          return ListViewCard(index, Key('$index'), todos, refresh);
        }),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            todos.insert(todos.length, Todo("New Todo"));
          });
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class ListViewCard extends StatefulWidget {
  final int index;
  final Key key;
  final List<Todo> todoList;
  VoidCallback callback;

  ListViewCard(this.index, this.key, this.todoList, this.callback);
  @override
  _ListViewCard createState() => _ListViewCard();
}

class _ListViewCard extends State<ListViewCard> {
  @override
  Widget build(BuildContext context) {
    return Card(
      child: ListTile(
        title: Text(widget.todoList[widget.index].text),
        trailing: IconButton(
          icon: Icon(Icons.delete),
          onPressed: () {
            todos.removeAt(widget.index);
            widget.callback();
            /*setState(() {
              todos.removeAt(widget.index);
            });*/
          },
        ),
        onTap: () {},
      ),
    );
  }
}
...