【Flutter】スワイプでリストの項目を削除する（Dismissible）

List表示されている項目を、スワイプで削除する方法を紹介します。

# Dismissibleをラップする
Listのアイテムを構成しているWidgetに**Dismissible**をラップします。

## 引数について
### key
ユニークなキーを指定する必要があります。
このキーが重複してしまうと、アニメーションがおかしくなったりするみたいです。
### background
アイテムをスワイプした時の背景を指定することができます。
スワイプで赤背景になるやつとかを実装できます。

```dart
background: Container(
              padding: EdgeInsets.only(
                right: 10,
              ),
              alignment: AlignmentDirectional.centerEnd,
              color: Colors.red,
              child: Icon(
                Icons.delete,
                color: Colors.white,
              ),
            ),
```
### direction
スワイプできる方向を指定できます。

```dart
direction: DismissDirection.endToStart,
```

|  | 方向 |
|:-----------|------------:|
| DismissDirection.endToStart | 右から左 |
| DismissDirection.startToEnd | 左から右 |
| DismissDirection.horizontal | 右から左・左から右    |
| DismissDirection.vertical   | 下から上・上から下    |
| DismissDirection.up         | 下から上 |
| DismissDirection.down       | 上から下 |

### confirmDismiss
スワイプのアニメーションが終わったタイミングで呼ばれます。
まだWidgetが破棄されていないため、本当に処理を実行して良いか等の確認を行ったりできます。

### onDismissed
スワイプでWidgetが破棄され、アニメーションが終わったタイミングで呼ばれます。
実際のデータの削除処理などはここで行うことになります。

また、どの方向にスワイプされたか取得できるため、スワイプ方向によって処理を分けることもできます。

```dart
onDismissed: (direction) {
              if (direction == DismissDirection.endToStart) {
                // 右から左にスワイプされた時
              } else {
                // それ以外
              }
            },
```

## サンプルコード
```dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter App',
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  List<String> _item = [
    '111',
    '222',
    '333',
    '444',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('リスト'),
      ),
      body: ListView.separated(
        separatorBuilder: (context, index) => Divider(
          height: 0.0,
        ),
        itemCount: _item.length,
        itemBuilder: (BuildContext context, int index) {
          final text = _item[index];
          return Dismissible(
            key: Key(text),
            background: Container(
              padding: EdgeInsets.only(
                right: 10,
              ),
              alignment: AlignmentDirectional.centerEnd,
              color: Colors.red,
              child: Icon(
                Icons.delete,
                color: Colors.white,
              ),
            ),
            direction: DismissDirection.endToStart,
            onDismissed: (direction) {
              // スワイプ後に実行される（削除処理などを書く）
              print('onDismissed');
            },
            child: ListTile(
              title: Text(
                text,
              ),
              onTap: () {},
            ),
          );
        },
      ),
    );
  }
}
```
## 実行結果
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663839/1365e0c3-b6dd-4546-5c86-1d337c2814fb.gif)