【Flutter】Dismissibleの使い方（リストをスライドして削除する）

# はじめに
Listをスライドすることで削除出来るような処理を作ろうと調べたので、それをまとめていこうと思います。


## この記事で分かること

- Dismissibleの使い方
- DismissDirectionの方向性


# 目次
1. 普通のList
1. Dismissibleを使用
1. DismissDirectionの方向を確認する
    1. Listを縦スクロール
    1. Listを横スクロール

## 1．普通のList

ここでの普通のListとは

- リストをただ単に並べただけ
    - タップしたり、横にスライドさせることは出来ない
    - 最低限のものとする

```dart
class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<int> items = List<int>.generate(100, (int index) => index);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: ListView.builder(
        itemCount: items.length,
        itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text(
              'Item ${items[index]}',
            ),
          );
        },
      ),
    );
  }
}

```

これを元に処理を追加していく

## 2．Dismissibleを使用
こちらに詳しく載っているので、良ければご覧ください。

https://docs.flutter.dev/cookbook/gestures/dismissible

ListTileをDismissibleで囲む

```dart
class _HomePageState extends State<HomePage> {
  List<int> items = List<int>.generate(100, (int index) => index);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: ListView.builder(
        itemCount: items.length,
        itemBuilder: (BuildContext context, int index) {
          return Dismissible(
            key: Key(items.toString()),
            onDismissed: (DismissDirection direction) {
              setState(() {
                items.removeAt(index);
              });
            },
            background: Container(
              color: Colors.red,
            ),
            child: ListTile(
              title: Text(
                'Item ${items[index]}',
              ),
            ),
          );
        },
      ),
    );
  }
}
```

Dismissibleで追記したこと

- key
    - リストの中の1部を指定するため
- onDismissed
    - リストを削除するため
- background
    - リストをスライドした時に見える背景色を指定するため

## 3．DismissDirectionの方向を確認する

DismissDirectionで方向を指定することが可能

### 3.1 Listを縦スクロール

- Listを縦スクロール
    - `scrollDirection: Axis.vertical`を指定
- スライド方向は横のみ
    - `direction: DismissDirection.horizontal`を指定
- スライド方向の指定
    - `DismissDirection.startToEnd`の場合
        - 「左から右」へのスライド
    - `DismissDirection.endToStart`の場合
        - 「右から左」へのスライド

```dart
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: ListView.builder(
        itemCount: items.length,
        scrollDirection: Axis.vertical, // リストのスクロール方向を縦に
        itemBuilder: (BuildContext context, int index) {
          return Dismissible(
            direction: DismissDirection.horizontal, // スライド方向を横に
            key: Key(items.toString()),
            onDismissed: (DismissDirection direction) {
              setState(() {
                items.removeAt(index);
              });

              if (direction == DismissDirection.startToEnd) {
                // 左から右
                print('StartToEnd');
              } else if (direction == DismissDirection.endToStart) {
                // 右から左
                print('EndToStart');
              }
            },
            background: Container(
              color: Colors.red,
            ),
            child: ListTile(
              title: Text(
                'Item ${items[index]}',
              ),
            ),
          );
        },
      ),
    );
  }
```

### 3.2 Listを横スクロール

- Listを横スクロール
    - `scrollDirection: Axis.horizontal`を指定
    - widthの大きさを指定しないとエラーが出る
- スライド方向は縦のみ
    - `direction: DismissDirection.vertical`を指定
- スライド方向の指定
    - `DismissDirection.up`の場合
        - 「下から上」へのスライド
    - `DismissDirection.down`の場合
        - 「上から下」へのスライド

```dart
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: ListView.builder(
        itemCount: items.length,
        scrollDirection: Axis.horizontal, // リストのスクロール方向を横に
        itemBuilder: (BuildContext context, int index) {
          return Dismissible(
            direction: DismissDirection.vertical, // スライド方向を縦に
            key: Key(items.toString()),
            onDismissed: (DismissDirection direction) {
              setState(() {
                items.removeAt(index);
              });

              if (direction == DismissDirection.up) {
                // 下から上
                print('Up');
              } else if (direction == DismissDirection.down) {
                // 上から下
                print('Down');
              }
            },
            background: Container(
              color: Colors.red,
            ),
            child: Container(
              width: 100, // 横方向の大きさを指定
              child: ListTile(
                title: Text(
                  'Item ${items[index]}',
                ),
              ),
            ),
          );
        },
      ),
    );
  }
```


# 参考資料

https://api.flutter.dev/flutter/widgets/Dismissible-class.html

https://docs.flutter.dev/cookbook/gestures/dismissible

https://api.flutter.dev/flutter/widgets/DismissDirection.html


# おわりに
ここまで読んでいただき、ありがとうございました。
何かありましたらコメントをお願いします。