アプリで検索機能を提供するには、アプリバーの項目として SearchView
ウィジェットを使用することをおすすめします。アプリバーのすべての項目と同様に、SearchView
を常に表示するか、スペースがある場合にのみ表示するかを定義できます。折りたたみ可能なアクションとして定義することもできます。この場合、最初は SearchView
がアイコンとして表示され、ユーザーがアイコンをタップするとアプリバー全体が検索フィールドになります。
SearchView をアプリバーに追加する
SearchView
ウィジェットをアプリバーに追加するには、プロジェクト内に res/menu/options_menu.xml
という名前のファイルを作成し、下記のコードをそのファイルに含めます。このコードは、アプリバーで使用するアイコンや項目のタイトルなど、検索項目の作成方法を定義するものです。collapseActionView
属性を使用すると、SearchView
を展開してアプリバー全体に表示したり、使用しないときには折りたたんでアプリバーの通常の項目に戻したりすることができます。ハンドセット デバイス上ではアプリバーのスペースが限られるので、collapsibleActionView
属性を使ってユーザー エクスペリエンスの向上を図ることをおすすめします。
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/search" android:title="@string/search_title" android:icon="@drawable/ic_search" android:showAsAction="collapseActionView|ifRoom" android:actionViewClass="androidx.appcompat.widget.SearchView" /> </menu>
よりアクセスしやすい検索アイコンが必要な場合は、/res/drawable
フォルダに ic_search.xml
ファイルを作成し、次のコードを追加します。
<vector android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/> </vector>
SearchView
をアプリバーに表示するには、アクティビティの onCreateOptionsMenu()
メソッドで XML メニュー リソース res/menu/options_menu.xml
をインフレートします。
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.options_menu, menu) return true }
アプリを実行すると、次のような結果が生成されます。

SearchView
はアプリのアプリバーに表示されますが、まだ機能しません。検索アイコンをタップすると、次のように表示されます。

SearchView
の動作。
SearchView
を機能させるには、SearchView
の動作を定義する必要があります。
検索構成を作成する
検索構成は、SearchView
の動作を指定し、res/xml/searchable.xml
ファイルで定義します。検索構成には、少なくとも Android マニフェスト内の <application> 要素または <activity> 要素の android:label
属性と同じ値を持つ android:label
属性を含める必要があります。ただし他にも、android:hint
属性を指定して、検索ボックスに何を入力するかのヒントを表示することをおすすめします。
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:hint="@string/search_hint" />
アプリのマニフェスト ファイルで、res/xml/searchable.xml
ファイルを指す <meta-data>
要素を宣言します。SearchView
を表示する <activity>
内で要素を宣言します。
<activity android:name=".SearchResultsActivity" android:exported="false" android:label="@string/title_activity_search_results" android:launchMode="singleTop" android:theme="@style/Theme.AppCompat.Light"> <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity>
作成した onCreateOptionsMenu()
メソッドで、setSearchableInfo(SearchableInfo)
を呼び出して検索構成を SearchView
に関連付けます。
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.options_menu, menu) val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager val searchView = menu.findItem(R.id.search).actionView as SearchView val component = ComponentName(this, SearchResultsActivity::class.java) val searchableInfo = searchManager.getSearchableInfo(component) searchView.setSearchableInfo(searchableInfo) return true }
getSearchableInfo()
を呼び出すと、検索構成の XML ファイルから作成される SearchableInfo
オブジェクトを取得できます。検索構成が SearchView
に正しく関連付けられ、ユーザーがクエリを送信すると、SearchView
は ACTION_SEARCH
インテントを持つアクティビティを開始します。ここで、このインテントをフィルタし、その検索クエリを処理するアクティビティが必要です。
検索可能アクティビティを作成する
検索可能なアクティビティは ACTION_SEARCH
インテントをフィルタし、データセットでクエリを検索します。検索可能なアクティビティを作成するには、必要なアクティビティを宣言して、ACTION_SEARCH
インテントをフィルタします。
<activity android:name=".SearchResultsActivity" ... > ... <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> ... </activity>
検索可能なアクティビティでは、onCreate()
メソッド内で ACTION_SEARCH
インテントを確認し、処理します。
Kotlin
class SearchResultsActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_search_results) handleIntent(intent) } override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) handleIntent(intent) } private fun handleIntent(intent: Intent) { if (Intent.ACTION_SEARCH == intent.action) { val query = intent.getStringExtra(SearchManager.QUERY) Log.d("SEARCH", "Search query was: $query") } } }
これで、SearchView
はユーザーのクエリを受け付けて、ACTION_SEARCH
インテントを持つ検索可能なアクティビティを開始できます。
検索クエリを取得したら、それを ViewModel
に渡すことができます。アーキテクチャの他のレイヤでこのクエリを使用して、表示する検索結果を取得できます。