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

API サーフェス
検索バーを実装するには、SearchBar
コンポーザブルを使用します。このコンポーザブルの主なパラメータは次のとおりです。
inputField
: 検索バーの入力フィールドを定義します。通常はSearchBarDefaults.InputField
を使用します。これにより、次のカスタマイズが可能になります。query
: 入力フィールドに表示されるクエリテキスト。onQueryChange
: クエリ文字列の変更を処理する Lambda。
expanded
: 検索バーが展開されて候補が表示されているか、フィルタされた結果が表示されているかを示すブール値。onExpandedChange
: プルダウンの展開状態の変更を処理する Lambda。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
をご覧ください。
結果

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