Flutter で検索バーを実装したら意外と簡単だったけど、ちょっと困った 😨 




## はじめに
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311982/eb198b1f-1f8c-48a7-0e22-6d2bd49ffdd9.gif" width="50%" >
こういうの実装したいけど、難しそうだなー

↓

この [パッケージ](<https://pub.dev/packages/flappy_search_bar>) 使ったら思ったよりも簡単でした！
なので、ついでに困ったこともまとめます 📝
つい最近 Flutter 始めたばかりで、まだまだ勉強中なので、優しい目で読んでいただけると嬉しいです。



## インストール

`flappy_search_bar` を使うことで、始めの動画のような検索バーを実装できます。

### 1. `pubspec.yaml` ファイルに追加します。

```yaml
dependencies:
  flappy_search_bar: ^1.7.2
```

### 2. インストールします。

```shell
$ flutter pub get
```

※ エディターが `flutter pub get` をサポートしている場合もあります。詳細については、エディターのドキュメントを確認してください。

### 3. インポートします。

```dart
import 'package:flappy_search_bar/flappy_search_bar.dart';
```





## 使い方

下記のように実装します。

```dart
@override
Widget build(BuildContext context) {
  return Padding(
    padding: const EdgeInsets.all(10.0),
    child: SearchBar<Application>(
      onSearch: search,
      onItemFound: (Application app, int index) {
        return ListTile(
          // アプリ情報から必要な情報を取得して画面に表示する処理を行っています。
        );
      },
    ),
  );
}

/// 検索対象のアプリ情報を検索しています。
Future<List<Application>> search(String search) async {
  final apps = await widget.getAppsFunction;
  var searchApps = apps
      .where(
          (app) =>
          app.appName.contains(search))
      .toList();
  return searchApps;
}
```



### パラメータ

| パラメータ名 | 概要                                                 | 必須 | デフォルト値 |
| ------------ | ---------------------------------------------------- | ---- | ------------ |
| onSearch     | 検索処理を指定する（上の例では search メソッドです） | ◯    | -            |
| onItemFound  | 検索結果と index で表示処理を指定する                | ◯    | -            |
| minimumChars | 検索を開始する最小文字数を指定する                   | -    | 3            |

※ 上記以外にもパラメータがあるので、必要であれば[ドキュメント](https://pub.dev/packages/flappy_search_bar#parameters)を確認してください。



### 実装した結果がこちら 👇
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311982/fb122570-437d-63c9-9fb3-d89c2682f77e.gif" width="50%" >
※ この例ではわかりやすいように端末にインストールされているアプリの情報を表示させています。



## 困ったこと

### 検索開始が３文字目事件 🙀
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311982/abf8d63a-df8b-0ef0-36b7-7e0a1b9cb4cb.gif" width="50%" >
1文字打っても何も反応がなく、3文字目を打ったときに検索されている…

↓

実は前述の minimumChars のデフォルト値が関係していました！

| パラメータ名 | 概要                     | 必須 | デフォルト値 |
| ------------ | ------------------------ | ---- | ------------ |
| minimumChars | 検索を開始する最小文字数を指定する | -    | **3**        |



ということで、onSearch の下に `minimumChars: 1` を追加しました ✨

```dart
@override
Widget build(BuildContext context) {
  return Padding(
    padding: const EdgeInsets.all(10.0),
    child: SearchBar<Application>(
      onSearch: search,
      minimumChars: 1,
      onItemFound: (Application app, int index) {
        return ListTile(
          // アプリ情報から必要な情報を取得して画面に表示する処理を行っています。
        );
      },
    ),
  );
}
```



↓
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311982/eb198b1f-1f8c-48a7-0e22-6d2bd49ffdd9.gif" width="50%" >
※ ただし検索が重い処理などは１文字単位で検索するとメモリが大変なことになります。ご注意ください。



### y と Y 事件

`y` と打った時は 『YouTube』 が出てこないのに `Y` と打ったらヒットする…（なんとなくそんな気はしていた）

↓

問題の実装 👇

```dart
Future<List<Application>> search(String search) async {
  final apps = await widget.getAppsFunction;
  var searchApps = apps
      .where(
          (app) =>
          app.appName.contains(search))
      .toList();
  return searchApps;
}
```

この書き方だと、大文字小文字を区別して検索していました… **GENMITSU !!**

↓

厳密に検索する必要はないので、 `toLowerCase()` を追加して小文字に変換することで解決しました！

```dart
Future<List<Application>> search(String search) async {
  final apps = await widget.getAppsFunction;
  var searchApps = apps
      .where(
          (app) =>
          app.appName?.toLowerCase()?.contains(search?.toLowerCase()))
      .toList();
  return searchApps;
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311982/766bb091-05f3-7073-31ed-f87c3496db15.gif" width="50%" >
ﾜｰｲ (/･ω･)/

## まとめ

検索バーは思ったより簡単に実装できて驚きでした！