検索インターフェースを作成する

アプリに検索機能を追加する準備ができたら、Android で、アクティビティ ウィンドウの上部に表示される検索ダイアログまたはレイアウトに挿入できる検索ウィジェットを使用して、ユーザー インターフェースを実装できます。検索ダイアログとウィジェットは、どちらもユーザーの検索クエリをアプリの特定のアクティビティに配信できます。これにより、ユーザーは検索ダイアログまたは検索ウィジェットが利用可能なアクティビティから検索を開始することができ、システムは適切なアクティビティを起動して検索を実行し、結果を表示します。

検索ダイアログと検索ウィジェットでは以下の機能も使用できます。

  • 音声検索
  • 最近のクエリに基づく検索候補
  • アプリデータの実際の結果と一致する検索候補

このドキュメントでは、Android システムが支援する検索インターフェースを提供するようにアプリをセットアップし、検索ダイアログまたは検索ウィジェットを使用して検索クエリを提供する方法について説明します。

関連リソース:

基本情報

始める前に、検索ダイアログと検索ウィジェットのどちらを使用して検索インターフェースを実装するかを決めてください。利用できる検索機能は同じですが、その方法が若干異なります。

  • 検索ダイアログは、Android システムによって制御される UI コンポーネントです。ユーザーが検索ダイアログを有効にすると、アクティビティの上部に検索ダイアログが表示されます。

    検索ダイアログ内のイベントはすべて、Android システムが制御します。ユーザーがクエリを送信すると、検索処理のために指定したアクティビティにクエリが配信されます。このダイアログでは、ユーザーの入力中に検索候補を表示することもできます。

  • 検索ウィジェットSearchView のインスタンスであり、レイアウト内のどこにでも配置できます。デフォルトでは、検索ウィジェットは標準の EditText ウィジェットと同じように動作し、何も行いませんが、検索ダイアログと同様に、Android システムがすべての入力イベントを処理し、適切なアクティビティにクエリを配信し、検索候補を提示するように構成できます。

ユーザーが検索ダイアログまたは検索ウィジェットから検索を実行すると、システムによって Intent が作成され、そこにユーザークエリが保存されます。システムは、検索を処理するために宣言したアクティビティ(「検索可能アクティビティ」)を開始し、インテントに渡します。この種のアシスト検索に対応するようにアプリをセットアップするには、次のものが必要です。

  • 検索構成
    検索ダイアログまたは検索ウィジェットの一部の設定を構成する XML ファイル。音声検索、検索候補、検索ボックスのヒントテキストなどの機能の設定が含まれます。
  • 検索可能なアクティビティ
    検索クエリを受け取り、データの検索と検索結果の表示を行う Activity
  • 検索インターフェース。次のいずれかを提供します。
    • 検索ダイアログ
      検索ダイアログはデフォルトで非表示になっています。ユーザーが [Search] ボタンをタップして onSearchRequested() を呼び出したときに、画面上部に表示されます。
    • SearchView ウィジェット
      検索ウィジェットを使用すると、アプリバーのアクション ビューを含め、アクティビティ内の任意の場所に検索ボックスを配置できます。

このドキュメントの残りの部分では、検索構成と検索可能なアクティビティを作成する方法と、検索ダイアログまたは検索ウィジェットを使用して検索インターフェースを実装する方法について説明します。

検索可能な構成を作成する

最初に必要なものは、検索構成と呼ばれる XML ファイルです。検索ダイアログまたは検索ウィジェットの特定の UI 要素を構成し、候補や音声検索などの機能の動作を定義します。このファイルは伝統的に searchable.xml という名前で、res/xml/ プロジェクト ディレクトリに保存する必要があります。

検索構成ファイルには、ルートノードとして <searchable> 要素を含め、1 つ以上の属性を指定する必要があります。次の例をご覧ください。

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_label"
    android:hint="@string/search_hint" >
</searchable>

android:label 属性は唯一の必須属性です。これは文字列リソースを指します。文字列リソースにはアプリ名を指定する必要があります。このラベルは、クイック検索ボックスの検索候補を有効にするまでユーザーに表示されません。有効にすると、システム設定の検索対象アイテムリストにラベルが表示されます。

必須ではありませんが、常に android:hint 属性を含めることをおすすめします。この属性により、ユーザーがクエリを入力する前に、検索ボックスにヒントの文字列が表示されます。ヒントは、ユーザーが何を検索できるかに関する重要な手がかりであるため重要です。

<searchable> 要素には、他にもいくつかの属性を指定できます。 ただし、検索候補音声検索などの機能を追加するまで、ほとんどの属性は必要ありません。検索構成ファイルの詳細については、検索構成のリファレンス ドキュメントをご覧ください。

検索可能なアクティビティを作成する

検索可能なアクティビティとは、クエリ文字列に基づいて検索を行い、検索結果を表示するアプリ内の Activity のことです。

ユーザーが検索ダイアログまたは検索ウィジェットで検索を実行すると、システムによって検索可能なアクティビティが開始され、ACTION_SEARCH アクションを使用して Intent で検索クエリが配信されます。検索可能なアクティビティは、インテントの QUERY エクストラからクエリを取得し、データを検索して結果を表示します。

検索ダイアログや検索ウィジェットはアプリの他のアクティビティに含めることができるため、検索クエリを適切に配信できるように、どのアクティビティが検索可能アクティビティであるかをシステムが認識している必要があります。そのため、まず Android マニフェスト ファイルで検索可能なアクティビティを宣言します。

検索可能なアクティビティを宣言する

まだ作成していない場合は、検索を実行して結果を表示する Activity を作成します。まだ検索機能を実装する必要はありません。マニフェストで宣言できるアクティビティを作成するだけです。マニフェストの <activity> 要素内で、次の操作を行います。

  1. <intent-filter> 要素で、ACTION_SEARCH インテントを受け入れるようにアクティビティを宣言します。
  2. <meta-data> 要素で使用する検索構成を指定します。

これを次の例に示します。

<application ... >
    <activity android:name=".SearchableActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
    </activity>
    ...
</application>

<meta-data> 要素には、値が "android.app.searchable"android:name 属性と、検索可能な構成ファイルへの参照を含む android:resource 属性を含める必要があります。上記の例では、res/xml/searchable.xml ファイルを参照しています。

検索を実行する

検索可能なアクティビティをマニフェストで宣言したら、次の手順で検索可能なアクティビティ内で検索を行います。

  1. クエリを受信します
  2. データを検索する
  3. 結果を提示する

クエリを受信する

ユーザーが検索ダイアログまたは検索ウィジェットから検索を実行すると、システムによって検索可能なアクティビティが開始され、ACTION_SEARCH インテントが送信されます。このインテントには、QUERY 文字列エクストラに検索クエリが含まれています。アクティビティの開始時にこのインテントを確認し、文字列を抽出します。たとえば、検索可能なアクティビティの開始時に検索クエリを取得する方法は以下のとおりです。

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.search)

    // Verify the action and get the query.
    if (Intent.ACTION_SEARCH == intent.action) {
        intent.getStringExtra(SearchManager.QUERY)?.also { query ->
            doMySearch(query)
        }
    }
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.search);

    // Get the intent, verify the action, and get the query.
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      doMySearch(query);
    }
}

QUERY 文字列は常に ACTION_SEARCH インテントに含まれます。上記の例では、クエリが取得され、ローカルの doMySearch() メソッドに渡され、そこで実際の検索操作が実行されます。

データを検索

データの保存と検索のプロセスはアプリによって異なります。データの保存と検索はさまざまな方法で行うことができますが、このドキュメントでは説明しません。ニーズとデータ形式の観点からデータを保存および検索する方法を検討してください。適用可能なヒントは次のとおりです。

  • データがデバイスの SQLite データベースに保存されている場合、LIKE クエリではなく FTS3 を使用して全文検索を実行すると、テキストデータ全体にわたる検索の堅牢性が向上し、結果の生成が大幅に高速化します。FTS3 については sqlite.org を、Android での SQLite については SQLiteDatabase クラスをご覧ください。
  • データがオンラインで保存されている場合、ユーザーのデータ接続によって、ユーザーが感じられる検索パフォーマンスが妨げられることがあります。検索結果が返されるまで、進行状況インジケーターを表示することをおすすめします。ネットワーク API のリファレンスについては android.net を、進行状況インジケーターを表示する方法については ProgressBar をご覧ください。

結果の提示

データが存在する場所や検索方法に関係なく、Adapter を使用して検索結果を検索可能なアクティビティに返すことをおすすめします。これにより、すべての検索結果を RecyclerView に表示できます。データが SQLite データベース クエリから取得される場合、CursorAdapter を使用して結果を RecyclerView に適用できます。データのフォーマットが異なる場合は、BaseAdapter の拡張機能を作成できます。

Adapter は、一連のデータの各項目を View オブジェクトにバインドします。AdapterRecyclerView に適用されると、各データが個別のビューとしてリストに挿入されます。Adapter は単なるインターフェースであるため、Cursor からデータをバインドするには CursorAdapter などの実装が必要です。既存の実装がデータに対応していない場合は、BaseAdapter から独自の実装を実装できます。

検索ダイアログを使用する

検索ダイアログの画面上部にはフローティング検索ボックスが表示され、左側にはアプリアイコンがあります。検索ダイアログは、ユーザーの入力に応じて検索候補を表示できます。ユーザーが検索を実行すると、検索を実行する検索可能アクティビティに検索クエリが送信されます。

デフォルトでは、検索ダイアログはユーザーがアクティブにするまで常に非表示になっています。アプリで検索ダイアログを有効にするには、onSearchRequested() を呼び出します。ただし、このメソッドは、アクティビティの検索ダイアログを有効にするまで機能しません。

検索ダイアログで検索できるようにするには、検索ダイアログから検索クエリを受け取る必要のある検索可能なアクティビティをシステムに指示します。たとえば、検索可能なアクティビティの作成に関する前のセクションでは、SearchableActivity という名前の検索可能なアクティビティが作成されます。個別のアクティビティ(OtherActivity という名前のアクティビティなど)で検索ダイアログを表示し、検索を SearchableActivity に配信するには、マニフェストで SearchableActivityOtherActivity の検索ダイアログに使用する検索可能アクティビティであることを宣言します。

アクティビティの検索ダイアログ用に検索可能アクティビティを宣言するには、それぞれのアクティビティの <activity> 要素内に <meta-data> 要素を追加します。<meta-data> 要素には、検索可能なアクティビティのクラス名を指定する android:value 属性と、"android.app.default_searchable" の値を持つ android:name 属性を含める必要があります。

たとえば、検索可能なアクティビティ SearchableActivity と、検索ダイアログから実行される検索を SearchableActivity を使用して実行する別のアクティビティ OtherActivity の宣言は次のようになります。

<application ... >
    <!-- This is the searchable activity; it performs searches. -->
    <activity android:name=".SearchableActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
    </activity>

    <!-- This activity enables the search dialog to initiate searches
         in the SearchableActivity. -->
    <activity android:name=".OtherActivity" ... >
        <!-- Enable the search dialog to send searches to SearchableActivity. -->
        <meta-data android:name="android.app.default_searchable"
                   android:value=".SearchableActivity" />
    </activity>
    ...
</application>

検索に使用する検索可能なアクティビティを宣言する <meta-data> 要素が OtherActivity に含まれるようになったため、アクティビティは検索ダイアログを有効にします。ユーザーがこのアクティビティにいる場合でも、onSearchRequested() メソッドにより検索ダイアログが有効になります。ユーザーが検索を実行すると、システムが SearchableActivity を起動して ACTION_SEARCH インテントを渡します。

アプリ内のすべてのアクティビティで検索ダイアログを表示する場合は、各 <activity> ではなく、上記の <meta-data> 要素を <application> 要素の子として挿入します。このようにして、すべてのアクティビティは値を継承し、検索ダイアログを提供し、同じ検索可能なアクティビティに検索を配信します。検索可能なアクティビティが複数ある場合は、個々のアクティビティ内に異なる <meta-data> 宣言を配置することで、デフォルトの検索可能アクティビティをオーバーライドできます。

これで、アクティビティに対して検索ダイアログが有効になったので、アプリで検索を実行できるようになりました。

検索ダイアログを呼び出す

一部のデバイスには専用の検索ボタンがありますが、デバイスによってボタンの動作は異なる場合があります。また、多くのデバイスには検索ボタンがまったく搭載されていません。そのため、検索ダイアログを使用する場合は、onSearchRequested() を呼び出して検索ダイアログを有効にする検索ボタンを UI に用意する必要があります。

たとえば、オプション メニューまたは UI レイアウトに、onSearchRequested() を呼び出す検索ボタンを追加します。

また、「入力して検索」機能を有効にして、ユーザーがキーボードで入力を開始したときに検索ダイアログを有効にすることもできます。キー入力が検索ダイアログに挿入されます。アクティビティ内で「入力して検索」を有効にするには、アクティビティの onCreate() メソッドで setDefaultKeyMode または DEFAULT_KEYS_SEARCH_LOCAL を呼び出します。

検索ダイアログがアクティビティのライフサイクルに及ぼす影響

検索ダイアログは、画面の上部にフローティングする Dialog です。アクティビティ スタックは変更されないため、検索ダイアログが表示されたときに、ライフサイクル メソッド(onPause() など)は呼び出されません。入力フォーカスが検索ダイアログに与えられているため、アクティビティが入力フォーカスを失います。

検索ダイアログがアクティブになったときに通知を受け取るには、onSearchRequested() メソッドをオーバーライドします。このメソッドが呼び出されると、アクティビティで検索ダイアログへの入力フォーカスが失われたことが示されるため、ゲームの一時停止など、イベントに適した処理を行うことができます。検索コンテキスト データを渡す(このドキュメントの別のセクションで説明します)を除き、スーパークラスの実装を呼び出してメソッドを終了します。

Kotlin

override fun onSearchRequested(): Boolean {
    pauseSomeStuff()
    return super.onSearchRequested()
}

Java

@Override
public boolean onSearchRequested() {
    pauseSomeStuff();
    return super.onSearchRequested();
}

ユーザーが [戻る] ボタンをタップして検索をキャンセルすると、検索ダイアログが閉じ、アクティビティが入力フォーカスを取り戻します。setOnDismissListener()setOnCancelListener()、またはその両方を使用して、検索ダイアログが閉じられたときに通知されるように登録できます。OnDismissListener は検索ダイアログを閉じるたびに呼び出されるため、登録する必要があるのはこれだけです。OnCancelListener は、ユーザーが検索ダイアログを明示的に終了したイベントにのみ関連しているため、検索の実行時に呼び出されることはありません。検索を実行すると、検索ダイアログは自動的に消えます。

現在のアクティビティが検索可能なアクティビティでない場合、ユーザーが検索を行うと、通常のアクティビティのライフサイクル イベントがトリガーされます。現在のアクティビティは onPause() を受け取ります。アクティビティの概要をご覧ください。ただし、現在のアクティビティが検索可能なアクティビティの場合は、次のいずれかが発生します。

  • デフォルトでは、検索可能なアクティビティが onCreate() への呼び出しで ACTION_SEARCH インテントを受け取り、アクティビティの新しいインスタンスがアクティビティ スタックの一番上に移動します。アクティビティ スタック内に検索可能なアクティビティのインスタンスが 2 つになったため、[戻る] ボタンをタップしても、検索可能なアクティビティが終了するのではなく、検索可能なアクティビティの前のインスタンスに戻ることができます。
  • android:launchMode"singleTop" に設定すると、検索可能なアクティビティは、onNewIntent(Intent) の呼び出しで ACTION_SEARCH インテントを受け取り、新しい ACTION_SEARCH インテントを渡します。たとえば、検索可能アクティビティの起動モードが "singleTop" の場合の対処方法は次のとおりです。

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.search)
        handleIntent(intent)
    }
    
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        handleIntent(intent)
    }
    
    private fun handleIntent(intent: Intent) {
        if (Intent.ACTION_SEARCH == intent.action) {
            intent.getStringExtra(SearchManager.QUERY)?.also { query ->
                doMySearch(query)
            }
        }
    }
    

    Java

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search);
        handleIntent(getIntent());
    }
    
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        handleIntent(intent);
    }
    
    private void handleIntent(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
          String query = intent.getStringExtra(SearchManager.QUERY);
          doMySearch(query);
        }
    }
    

    検索の実行に関するセクションのサンプルコードとは異なり、検索インテントを処理するすべてのコードが handleIntent() メソッドにあるため、onCreate()onNewIntent() の両方で実行できるようになりました。

    システムが onNewIntent(Intent) を呼び出しても、アクティビティは再起動されないため、getIntent() メソッドは onCreate() で受け取ったインテントと同じインテントを返します。そのため、onNewIntent(Intent) 内で setIntent(Intent) を呼び出す必要があります。これにより、今後 getIntent() を呼び出した場合に、アクティビティによって保存されたインテントが更新されます。

2 番目のシナリオでは、"singleTop" 起動モードを使用するのが一般的です。検索の完了後にユーザーが追加の検索を実行する可能性があるため、検索可能なアクティビティのインスタンスをアプリが複数作成することがないようにする必要があります。次の例に示すように、アプリ マニフェストで検索可能なアクティビティを "singleTop" 起動モードに設定することをおすすめします。

<activity android:name=".SearchableActivity"
          android:launchMode="singleTop" >
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data
          android:name="android.app.searchable"
          android:resource="@xml/searchable"/>
  </activity>

検索コンテキスト データを渡す

場合によっては、検索を実行するたびに、検索可能アクティビティ内の検索クエリを必要に応じて絞り込むことができます。ただし、ユーザーが検索を行ったアクティビティに基づいて検索条件を絞り込む場合は、検索可能なアクティビティに送信するインテントに追加データを指定できます。追加データは、ACTION_SEARCH インテントに含まれる APP_DATA Bundle で渡すことができます。

この種のデータを検索可能なアクティビティに渡すには、ユーザーが検索を実行できるアクティビティの onSearchRequested() メソッドをオーバーライドし、追加データで Bundle を作成し、startSearch() を呼び出して検索ダイアログを有効にします。次に例を示します。

Kotlin

override fun onSearchRequested(): Boolean {
    val appData = Bundle().apply {
        putBoolean(JARGON, true)
    }
    startSearch(null, false, appData, false)
    return true
}

Java

@Override
public boolean onSearchRequested() {
     Bundle appData = new Bundle();
     appData.putBoolean(SearchableActivity.JARGON, true);
     startSearch(null, false, appData, false);
     return true;
 }

true が返されると、このコールバック イベントが正常に処理され、startSearch() を呼び出して検索ダイアログを有効にしたことを示します。ユーザーがクエリを送信すると、追加したデータとともに検索可能なアクティビティに配信されます。次の例に示すように、APP_DATA Bundle から追加データを抽出して検索を絞り込むことができます。

Kotlin

val jargon: Boolean = intent.getBundleExtra(SearchManager.APP_DATA)?.getBoolean(JARGON) ?: false

Java

Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
if (appData != null) {
    boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
}

検索ウィジェットを使用する

アプリのトップバーに検索ビューが表示されている画像

図 1. アプリバーのアクション ビューとしての SearchView ウィジェット

検索ウィジェットは検索ダイアログと同じ機能を備えています。ユーザーが検索を実行すると適切なアクティビティが起動し、検索候補の表示や音声検索の実行が可能になります。検索ウィジェットをアプリバー内に配置できない場合は、代わりにアクティビティ レイアウト内の任意の場所に検索ウィジェットを配置します。

検索ウィジェットを構成する

検索構成検索可能なアクティビティを作成したら、SearchView ごとにアシスト検索を有効にします。そのためには、setSearchableInfo() を呼び出して、検索可能な構成を表す SearchableInfo オブジェクトを渡します。

SearchableInfo への参照を取得するには、SearchManager に対して getSearchableInfo() を呼び出します。

たとえば、SearchView をアプリバーのアクション ビューとして使用する場合は、次の例に示すように、onCreateOptionsMenu() コールバック中にウィジェットを有効にします。

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the options menu from XML.
    val inflater = menuInflater
    inflater.inflate(R.menu.options_menu, menu)

    // Get the SearchView and set the searchable configuration.
    val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
    (menu.findItem(R.id.menu_search).actionView as SearchView).apply {
        // Assumes current activity is the searchable activity.
        setSearchableInfo(searchManager.getSearchableInfo(componentName))
        setIconifiedByDefault(false) // Don't iconify the widget. Expand it by default.
    }

    return true
}

Java

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the options menu from XML.
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);

    // Get the SearchView and set the searchable configuration.
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
    // Assumes current activity is the searchable activity.
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false); // Don't iconify the widget. Expand it by default.

    return true;
}

これで、検索ウィジェットが構成され、検索可能なアクティビティに検索クエリが配信されます。検索ウィジェットの検索候補を有効にすることもできます。

アプリバーのアクション ビューの詳細については、アクション ビューとアクション プロバイダを使用するをご覧ください。

検索ウィジェットのその他の機能

SearchView ウィジェットには、必要な追加機能がいくつか用意されています。

送信ボタン
デフォルトでは、検索クエリを送信するボタンがないため、ユーザーはキーボードの Return キーを押して検索を開始する必要があります。「送信」ボタンを追加するには、setSubmitButtonEnabled(true) を呼び出します。
検索候補のクエリの絞り込み
検索候補を有効にすると、通常はユーザーが候補を選択することが期待されますが、検索クエリサジェストを絞り込んだい場合もあります。各候補の横にボタンを追加し、setQueryRefinementEnabled(true) を呼び出して検索ボックスに候補を挿入し、ユーザーが絞り込みます。
検索ボックスの表示 / 非表示を切り替える機能
デフォルトでは、検索ウィジェットは「アイコン化」されており、検索アイコン(虫メガネ)でのみ表示されます。ユーザーがアイコンをタップすると、検索ボックスが展開されて表示されます。上記の例に示すように、setIconifiedByDefault(false) を呼び出すと、デフォルトで検索ボックスを表示できます。setIconified() を呼び出して、検索ウィジェットの外観を切り替えることもできます。

SearchView クラスには、検索ウィジェットをカスタマイズできる API が他にもあります。ただし、ほとんどの機能は、Android システムを使用して検索クエリの配信や検索候補の表示を行うのではなく、すべてのユーザー入力を自身で処理する場合にのみ使用されます。

ウィジェットとダイアログの両方を使用する

検索ウィジェットをアクション ビューとしてアプリバーに挿入し、android:showAsAction="ifRoom" を設定してスペースがあればアプリバーに表示しても、検索ウィジェットがアクション ビューとして表示されない場合があります。オーバーフロー メニューにメニュー項目が表示されることがあります。たとえば、アプリが小さな画面で実行されている場合、検索ウィジェットを他のアクション アイテムやナビゲーション要素とともに表示するのに十分なスペースがアプリバーにないため、メニュー項目がオーバーフロー メニューに表示されます。オーバーフロー メニューに配置されたアイテムは通常のメニュー項目と同様に機能し、アクション ビュー(検索ウィジェット)は表示されません。

この状況に対処するには、検索ウィジェットを接続するメニュー項目で、ユーザーがオーバーフロー メニューから検索ダイアログを選択したときに、検索ダイアログを有効にする必要があります。これを実現するには、「検索」メニュー項目を処理する onOptionsItemSelected() を実装し、onSearchRequested() を呼び出して検索ダイアログを開きます。

アプリバー内のアイテムの仕組みと、この状況に対処する方法について詳しくは、アプリバーを追加するをご覧ください。

音声検索を追加

検索ダイアログまたは検索ウィジェットに音声検索機能を追加するには、検索可能な構成に android:voiceSearchMode 属性を追加します。音声プロンプトを起動する音声検索ボタンが追加されます。 ユーザーが話し終えると、音声文字変換された検索クエリが検索可能なアクティビティに送信されます。

これを次の例に示します。

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search_label"
    android:hint="@string/search_hint"
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" >
</searchable>

音声検索を有効にするには、値 showVoiceSearchButton が必要です。2 番目の値 launchRecognizer は、音声検索ボタンで、音声文字変換されたテキストを検索可能なアクティビティに返す認識ツールを起動する必要があることを指定します。

追加の属性(想定される言語や返される結果の最大数など)を指定して、音声検索の動作を指定できます。使用可能な属性の詳細については、検索構成のリファレンスをご覧ください。

検索候補を追加する

検索ダイアログと検索ウィジェットではどちらも、Android システムの支援を受けて、ユーザーの入力に応じて検索候補を提示できます。システムは候補のリストを管理し、ユーザーが候補を選択したときにそのイベントを処理します。

検索候補には次の 2 種類があります。

最近のクエリに基づく検索候補
これらの候補は、ユーザーが以前にアプリで検索クエリとして使用した単語です。詳しくは、カスタム検索候補の追加をご覧ください。
カスタム検索候補
ユーザーが検索しようとしているスペルやアイテムをすぐに選択できるように、独自のデータソースから提供される検索候補です。詳細については、カスタム検索候補を追加するをご覧ください。