1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Flutter] Dismissible でハマったエラー(初心者あるある?)

Last updated at Posted at 2022-03-08

Flutter で Dismissible を使用した際にハマったエラー

最近Flutter を触り出す ⇨ チュートリアルとしてTodoアプリ制作中 ⇨ 削除機能を追加しようとした際にエラー( ; ; )

1. Dismissible とは

リスト表示されている要素に対するスワイプ操作に任意の処理を割り当てることが出来るウィジェットです。

以下が Dismissible の公式ドキュメントです。
Flutter公式 Dismissible

エラー ~RangeError編~

↓修正前のソースコード↓
main.dart
import 'package:flutter/material.dart';

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

class MyWonderfulLifeApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Wonderful Life",
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: TodoListPage(),
    );
  }
}

class TodoListPage extends StatefulWidget {
  @override
  _TodoListPageState createState() => _TodoListPageState();
}

class _TodoListPageState extends State<TodoListPage> {
  List<String> todoList = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('リスト一覧'),
      ),
      body: ListView.builder(
          itemCount: todoList.length,
          itemBuilder: (context, index) {
            return Dismissible(
                key: UniqueKey(),
                direction: DismissDirection.endToStart,
                onDismissed: (direction) {
                  todoList.remove(todoList[index]);
                },
                background: Container(
                  alignment: AlignmentDirectional.centerEnd,
                  color: Colors.red,
                  child: const Padding(
                    padding: EdgeInsets.fromLTRB(0, 0, 10, 0),
                    child: Icon(
                      Icons.delete,
                      color: Colors.white,
                    ),
                  ),
                ),
                child: Card(
                  child: ListTile(
                    title: Text(todoList[index]),
                  ),
                ));
          }),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final newListText = await Navigator.of(context).push(
            MaterialPageRoute(builder: (context) {
              return TodoAddPage();
            }),
          );
          if (newListText != null) {
            setState(() {
              todoList.add(newListText);
            });
          }
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class TodoAddPage extends StatefulWidget {
  @override
  _TodoAddPageState createState() => _TodoAddPageState();
}

class _TodoAddPageState extends State<TodoAddPage> {
  String _text = '';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('リスト追加'),
      ),
      body: Container(
        padding: EdgeInsets.all(64),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              _text,
              style: TextStyle(color: Colors.blue),
            ),
            const SizedBox(height: 8),
            TextField(
              onChanged: (String value) {
                setState(() {
                  _text = value;
                });
              },
            ),
            const SizedBox(height: 8),
            Container(
              width: double.infinity,
              child: ElevatedButton(
                onPressed: () {
                  Navigator.of(context).pop(_text);
                },
                child: Text('リスト追加', style: TextStyle(color: Colors.white)),
              ),
            ),
            const SizedBox(height: 8),
            Container(
              width: double.infinity,
              child: TextButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: Text('キャンセル'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Todoアプリ制作時、 dissmissible を用いて削除機能を追加しようとした。
すると、以下の実行動画のように、3つ以上の要素を削除するとエラーが発生してしまう。。。

エラー実行画面.gif

スクリーンショット 2022-03-08 21.59.49.png

エラーメッセージ
RangeError (RangeError (index): Invalid value: Not in inclusive range 0..1: 3)

問題点と解決方法

どうやら Dismissible 内の onDismissed の動作内容が間違えていたようだ。

   onDismissed: (direction) {
   todoList.remove(todoList[index]);
      },

ではなく

   onDismissed: (direction) {
   setState(() {
   todoList.remove(todoList[index]);
      });
   },

という単純なミスでした(^_^;)

まだまだ勉強が足りません、、

修正後の動作↓↓

修正後 実行画面.gif

これで消し放題(^^)v

Todoアプリ制作時に参考にしたサイト↓

ps. こういう初歩的なミスをすると意外とハマってしまう、、

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?