AppBarに検索ボックスを設置する方法を、ViewとComposeそれぞれで説明する。
View(SearchView)
メニューリソースに SearchView を追加し、onCreateOptionsMenu() で設定する。
メニューリソースを作成する
res/menu/menu_main.xml に SearchView を追加する。
app:showAsAction="ifRoom|collapseActionView" を指定すると、AppBarにスペースがある場合はアイコンとして表示し、タップで展開するビヘイビアになる。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
android:title="検索"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView" />
</menu>
onCreateOptionsMenuで設定する
onCreateOptionsMenu() でメニューをinflateし、SearchView.OnQueryTextListener を設定する。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
val searchItem = menu.findItem(R.id.action_search)
val searchView = searchItem.actionView as SearchView
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
query?.let { search(it) }
searchView.clearFocus()
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
newText?.let { filterList(it) }
return true
}
})
return true
}
private fun search(query: String) {
// 検索処理
}
private fun filterList(query: String) {
// リアルタイムフィルタリング処理
}
}
onQueryTextSubmit() は検索ボタンまたはキーボードのEnterキー押下時に呼ばれる。onQueryTextChange() はテキスト変更のたびに呼ばれるため、インクリメンタルサーチに使用する。
展開状態を初期表示にする
アプリ起動時から検索ボックスを展開した状態にするには、expandActionView() を呼ぶ。
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
val searchItem = menu.findItem(R.id.action_search)
searchItem.expandActionView()
// ...
return true
}
ヒントテキストを設定する
searchView.queryHint = "キーワードを入力"
Compose(SearchBar)
Material3の SearchBar コンポーネントを使う。SearchBar は全画面表示の検索UIで、DockedSearchBar はコンテンツ内へ埋め込む形式のコンポーネントである。
依存関係を追加する
dependencies {
implementation("androidx.compose.material3:material3:1.3.1")
}
SearchBarを使う
@Composable
fun SearchScreen() {
var query by remember { mutableStateOf("") }
var active by remember { mutableStateOf(false) }
val results = remember(query) { filterItems(query) }
SearchBar(
inputField = {
SearchBarDefaults.InputField(
query = query,
onQueryChange = { query = it },
onSearch = { active = false },
expanded = active,
onExpandedChange = { active = it },
placeholder = { Text("キーワードを入力") },
leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) },
trailingIcon = {
if (query.isNotEmpty()) {
IconButton(onClick = { query = "" }) {
Icon(Icons.Default.Close, contentDescription = "クリア")
}
}
}
)
},
expanded = active,
onExpandedChange = { active = it },
) {
// 検索結果をサジェストとして表示
results.forEach { item ->
ListItem(
headlineContent = { Text(item) },
modifier = Modifier.clickable {
query = item
active = false
}
)
}
}
}
private fun filterItems(query: String): List<String> {
val items = listOf("Android", "Kotlin", "Jetpack Compose", "Material3")
return if (query.isEmpty()) emptyList()
else items.filter { it.contains(query, ignoreCase = true) }
}
DockedSearchBarを使う
DockedSearchBar はAppBar直下など、コンテンツの一部として検索ボックスを配置する場合に適している。展開してもオーバーレイ表示になり、画面全体を占有しない。
@Composable
fun DockedSearchScreen() {
var query by remember { mutableStateOf("") }
var active by remember { mutableStateOf(false) }
val results = remember(query) { filterItems(query) }
Column {
DockedSearchBar(
inputField = {
SearchBarDefaults.InputField(
query = query,
onQueryChange = { query = it },
onSearch = { active = false },
expanded = active,
onExpandedChange = { active = it },
placeholder = { Text("キーワードを入力") },
leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) },
)
},
expanded = active,
onExpandedChange = { active = it },
) {
results.forEach { item ->
ListItem(
headlineContent = { Text(item) },
modifier = Modifier.clickable {
query = item
active = false
}
)
}
}
// メインコンテンツ
}
}
参考
\確かな知識を身に着けたい、Androidアプリ開発を学びたい人にオススメ!/
