😎

M3のSearchBarを使ってみた

2022/12/24に公開

こちらはAndroid Advent Calendar 2022の12/23の記事です。
Android Advent Calendar 2022

Background

現状Composeな環境でAndroidxのSearchView相当のキーワード検索画面を実装するには、TextFieldを用いて自前で実装するが主流(だと思っている)。
しかしこれにはテキストフィールドのフォーカスやキーボードの表示/非表示などを自前で実装する必要があり、なかなか大変。
そんな状況だったが、最近SearchBarというComposableがM3に追加されてた(2022/12/23時点では未リリース)ので代替となるか試してみた。

Until now

まずこれまでのキーワード検索画面の実装について、以下のように
FocusRequester, FocusMangerを用いて画面遷移なども考慮したフォーカス管理、
KeyboardControllerを用いたソフトキーボードの出し入れなどなど色々と自前実装が必要で地味に大変だった。(詳細な実装例などはググると結構出てくるので割愛)

val focusManager = LocalFocusManager.current
val focusRequester = remember { FocusRequester() }
val keyboard = LocalSoftwareKeyboardController.current

LaunchedEffect(Unit) {
    focusRequester.requestFocus()
    if (keyword.isEmpty() && ...) {
        // NOP
    } else {
        keyboard?.hide()
    }
    ...
}

TextField(
   modifier = modifier
       .focusRequester(focusRequester)
   ...,
   value = input,
   onValueChange = { new -> input = new },
   keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
   keyboardActions = KeyboardActions(onSearch = { focusManager.clearFocus() }),
   ...
)

How to use SearchBar

最近このM3にSearchBarなるComposableが追加されたのでTextFieldを置き換えできるかを確認するためにちょっと触ってみた
ちなみに現時点(2022/12/23 23:45 JST)ではこのSearchBarを含んだM3はリリースされておらず、AndroidxのComposeのプロジェクトをビルドして触っている。
ビルド方法など気になる人はこちらを参考にやってみてください。
https://github.com/androidx/androidx/tree/androidx-main/compose#getting-started
※ 雑にいうとrepo使ってCloneして、frameworks/support package以下にあるAndroidx開発用のAndroid studioを起動してソースを読み込めれば諸々OK

結果同じような検索画面を提供するのであればこんな感じの実装になりそう

val focusManager = LocalFocusManager.current
SearchBar(
    query = input,
    onQueryChange = { new -> input = new },
    onSearch = { _ -> focusManager.clearFocus()},
    active = true,
    onActiveChange = { ... },
){
    // Search results, search suggestions, ...etc.
}

ComposeのDemoアプリをちょっといじってSearchBarを使った時の見た目

gifは目を細めてみてみてください。。。(3MBまでしか上げられないとか...)
アニメーションなんかは全部SearchBar側に実装されています。

ちょっと楽になった(?)けど、キーワード検索の画面だけじゃなく、検索結果の表示などに使えるのComposable(contents)などが一体化しているので使い勝手がちょっと違う。
ちなみにこの検索結果表示などはactiveのBooleanで制御している。(falseだとcontentsは非表示になる)

SearchBar自体の詳しい実装はこちらを参照ください。
https://github.com/androidx/androidx/blob/4055fd4fc2dcbd0a327e3b9c336480b6df0e279c/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.kt#L151
(TextFieldの実装を押し込めているだけではある)

Summary

結果、多少楽になるが、フォーカス管理などを完全にやめれるかというとそこまでではなかった。
また、フラグによって検索画面がactiveかどうかを管理していたり、検索結果や検索候補の表示(Composable)が一体化していたり使うシーンを選ぶ場合があるかも。
しかし、簡単にリッチな検索画面を作れるので、ハマるシーンでは積極的に使っていきたい。

Discussion