検索バーを使用して検索機能を実装します。検索バーは、ユーザーがキーワードやフレーズを入力してアプリ内の関連する結果を表示できるようにする、永続的な検索フィールドです。検索がアプリの主な機能である場合に推奨されます。

API サーフェス
検索バーを実装するには、SearchBar
コンポーザブルを使用します。このコンポーザブルの主なパラメータは次のとおりです。
inputField
: 検索バーの入力フィールドを定義します。通常はSearchBarDefaults.InputField
を使用し、次のカスタマイズが可能です。query
: 入力フィールドに表示されるクエリテキスト。onQueryChange
: クエリ文字列の変更を処理する Lambda。
expanded
: 検索バーが展開されて候補やフィルタされた結果が表示されているかどうかを示すブール値。onExpandedChange
: ドロップダウンの展開状態の変化を処理するラムダ。content
: この検索バーのコンテンツ。検索結果をinputField
の下に表示します。
候補が表示された検索バー
このスニペットは、候補を含む SearchBar
の基本的な実装を示しています。
@OptIn(ExperimentalMaterial3Api::class) @Composable fun SimpleSearchBar( textFieldState: TextFieldState, onSearch: (String) -> Unit, searchResults: List<String>, modifier: Modifier = Modifier ) { // Controls expansion state of the search bar var expanded by rememberSaveable { mutableStateOf(false) } Box( modifier .fillMaxSize() .semantics { isTraversalGroup = true } ) { SearchBar( modifier = Modifier .align(Alignment.TopCenter) .semantics { traversalIndex = 0f }, inputField = { SearchBarDefaults.InputField( query = textFieldState.text.toString(), onQueryChange = { textFieldState.edit { replace(0, length, it) } }, onSearch = { onSearch(textFieldState.text.toString()) expanded = false }, expanded = expanded, onExpandedChange = { expanded = it }, placeholder = { Text("Search") } ) }, expanded = expanded, onExpandedChange = { expanded = it }, ) { // Display search results in a scrollable column Column(Modifier.verticalScroll(rememberScrollState())) { searchResults.forEach { result -> ListItem( headlineContent = { Text(result) }, modifier = Modifier .clickable { textFieldState.edit { replace(0, length, result) } expanded = false } .fillMaxWidth() ) } } } } }
コードに関する主なポイント
rememberSaveable
を使用すると、検索バーの展開状態と折りたたみ状態が構成変更後も保持されます。構成の変更時にアクティビティが破棄される前に、保存された値をホスト アクティビティのsavedInstanceState
バンドルに書き込みます。semantics
修飾子は TalkBack の移動順序を制御します。isTraversalGroup
は、すべての子コンポーザブルをグループ化するためにBox
に設定されます。traversalIndex
は、TalkBack が各グループ ピアからアクセシビリティ情報を読み取る順序を指定するために設定されます。TalkBack は、1
などの正の値を持つピアの前に、-1
などの負の値を持つピアのユーザー補助情報を読み上げます。値は浮動小数点数であるため、各ピアの-1.0
と1.0
の間に値を設定することで、多くのピアのカスタム順序を指定できます。
SearchBar
には、ユーザー入力用のinputField
と、検索候補を表示するためのColumn
が含まれています。SearchBarDefaults.InputField
は入力フィールドを作成し、ユーザー クエリの変更を処理します。onQueryChange
は、テキスト入力を処理し、入力フィールドのテキストが変更されるたびに状態を更新します。The expanded
状態は候補リストの表示を制御します。
searchResults.forEach { result -> … }
はsearchResults
リストを反復処理し、結果ごとにListItem
を作成します。ListItem
がクリックされると、textFieldState
が更新され、検索バーが折りたたまれ、textField
に選択された検索結果が入力されます。
結果

フィルタされたリストを含む検索バー
この例は、ユーザーの検索クエリに基づいてリストをフィルタする SearchBar
を示しています。
@OptIn(ExperimentalMaterial3Api::class) @Composable fun CustomizableSearchBar( query: String, onQueryChange: (String) -> Unit, onSearch: (String) -> Unit, searchResults: List<String>, onResultClick: (String) -> Unit, // Customization options placeholder: @Composable () -> Unit = { Text("Search") }, leadingIcon: @Composable (() -> Unit)? = { Icon(Icons.Default.Search, contentDescription = "Search") }, trailingIcon: @Composable (() -> Unit)? = null, supportingContent: (@Composable (String) -> Unit)? = null, leadingContent: (@Composable () -> Unit)? = null, modifier: Modifier = Modifier ) { // Track expanded state of search bar var expanded by rememberSaveable { mutableStateOf(false) } Box( modifier .fillMaxSize() .semantics { isTraversalGroup = true } ) { SearchBar( modifier = Modifier .align(Alignment.TopCenter) .semantics { traversalIndex = 0f }, inputField = { // Customizable input field implementation SearchBarDefaults.InputField( query = query, onQueryChange = onQueryChange, onSearch = { onSearch(query) expanded = false }, expanded = expanded, onExpandedChange = { expanded = it }, placeholder = placeholder, leadingIcon = leadingIcon, trailingIcon = trailingIcon ) }, expanded = expanded, onExpandedChange = { expanded = it }, ) { // Show search results in a lazy column for better performance LazyColumn { items(count = searchResults.size) { index -> val resultText = searchResults[index] ListItem( headlineContent = { Text(resultText) }, supportingContent = supportingContent?.let { { it(resultText) } }, leadingContent = leadingContent, colors = ListItemDefaults.colors(containerColor = Color.Transparent), modifier = Modifier .clickable { onResultClick(resultText) expanded = false } .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 4.dp) ) } } } } }
コードに関する主なポイント
onQueryChange
ラムダ関数は、ユーザーが検索バーでテキストを入力または削除するたびに呼び出されます。SearchBarDefaults.InputField
には、入力フィールドの先頭に検索アイコンを追加するleadingIcon
と、入力フィールドの末尾に「その他のオプション」アイコンを追加するtrailingIcon
が含まれています。ここでは、ユーザーに並べ替えとフィルタのオプションを提供できます。onSearch = { … }
はonSearch
ラムダを呼び出し、検索が送信されると検索バーを折りたたみます。LazyColumn
は、大量の検索結果を効率的に処理します。searchResults
リストを反復処理し、各結果をListItem
として表示します。- 各
ListItem
コンポーザブルは、アイテムのテキスト、追加情報を表示するテキスト、アイテムのleadingContent
としての星アイコンを表示します。この例では、アイテムをお気に入りに追加するオプションが表示されています。 - フィルタリング ロジックについては、GitHub の完全なソースコードの
CustomizableSearchBarExample
をご覧ください。
結果

参考情報
- マテリアル デザイン: 検索バー