当您准备好为应用添加搜索功能时,Android 可以帮助您 通过顶部显示的搜索对话框实现界面 或您可以插入布局中的搜索微件。 搜索对话框和搜索微件均可将用户的搜索查询传递给 应用内的特定活动这样,用户就可以从任意区域发起搜索 activity,其中搜索对话框或 widget 可用,并且系统启动 执行搜索和显示结果所需的相应 activity。
搜索对话框和搜索微件提供的其他功能包括:
- 语音搜索
- 基于近期查询的搜索建议
- 与应用数据中的实际结果相符的搜索建议
本文档介绍了如何设置您的应用以提供搜索界面 在 Android 系统的帮助下投放搜索查询 搜索对话框或搜索微件。
相关资源:
基础知识
在开始之前,请确定您是否要实现搜索界面 搜索微件。它们提供的搜索相同 只不过在方式上稍有不同
- 搜索对话框是一个界面组件,由
Android 系统。用户激活搜索对话框后,搜索对话框的
activity 的顶部。
Android 系统控制搜索对话框中的所有事件。当 当用户提交查询时,系统会将该查询传递给 来处理搜索。该对话框还可提供 在用户输入内容时提供建议。
- 搜索微件是
SearchView
放置在布局中的任意位置。默认情况下,搜索微件的行为类似于 标准EditText
并且不执行任何操作,但您可以对其进行配置 系统处理所有输入事件,将查询传送到相应的 以及提供搜索建议 对话框。
当用户从搜索对话框或搜索微件中执行搜索时,
系统会创建一个
Intent
和
其中存储了用户查询然后,系统会启动
声明用于处理搜索(即“可搜索 activity”),并提供
intent。要设置您的应用以使用此类辅助搜索,您需要
以下:
- 搜索配置
- 此 XML 文件用于为搜索对话框或搜索微件配置某些设置。 其中包括语音搜索、搜索建议 和提示文字。
- 可搜索的 activity
Activity
接收搜索查询、搜索您的数据并显示搜索 结果。- 搜索界面,由以下任一项提供:
- 搜索对话框
- 默认情况下,搜索对话框处于隐藏状态。它会显示在 当你通话时屏幕
onSearchRequested()
当用户点按您的搜索按钮时触发。SearchView
微件- 通过使用搜索微件,您可以将搜索框放在 包括应用栏中的操作视图。
本文档的其余部分介绍了如何创建搜索配置 以及如何使用 搜索对话框或搜索微件。
创建可搜索配置
首先,您需要一个称为
搜索配置。
它用于配置搜索对话框或搜索微件的某些界面方面,并定义如何
以及语音搜索等功能的行为。此文件一直是
名为 searchable.xml
,必须保存在 res/xml/
项目目录中。
搜索配置文件必须包含
<searchable>
元素作为其根节点,并指定一个或多个属性,如
示例:
<?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
可搜索 activity 是指应用中执行搜索操作的 Activity
,
基于查询字符串进行搜索,并显示搜索结果。
当用户在搜索对话框或搜索微件中执行搜索时,系统会
启动可搜索 activity 并以
Intent
替换为
ACTION_SEARCH
操作。可搜索 Activity 会从 intent 的
QUERY
extra,然后搜索您的数据并显示结果。
因为您可以将搜索对话框或搜索微件包含在 您的应用,系统必须知道哪个 activity 是您的可搜索 activity, 确保它可以正确提供搜索查询。因此,首先声明可供搜索的 Android 清单文件中的 activity。
声明可搜索 activity
如果您还没有 Activity
,请创建一个执行
搜索和显示结果。您无需实施搜索
只需创建一个可在
清单。在清单的
<activity>
元素,请执行以下操作:
- 在
ACTION_SEARCH
<intent-filter>
元素。 - 指定要在
<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:name
属性,值为
"android.app.searchable"
和android:resource
属性与可搜索配置文件的引用。在
它引用了 res/xml/searchable.xml
文件。
执行搜索
在清单中声明可搜索 Activity 后,请按照下面的 在可搜索 Activity 中执行搜索的步骤:
接收查询
当用户从搜索对话框或搜索微件中执行搜索时,系统会
启动您的可搜索 activity 并向其发送 ACTION_SEARCH
intent。此 intent 在 QUERY
字符串中携带搜索查询
extra。在 activity 启动时检查此 intent 并提取字符串。
例如,下面介绍了如何在
活动开始:
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
intent。在前面的示例中,查询为
并将其传递给本地 doMySearch()
方法,其中
实际搜索操作完成时的情况。
搜索您的数据
存储和搜索数据的过程对于您的应用来说是唯一的。您可以 可通过多种方式存储和搜索数据,本文档并未介绍具体方法。 考虑如何根据您的需求和数据存储和搜索数据 格式。以下是您或许可以采用的提示:
- 如果您的数据存储在设备上的 SQLite 数据库中,请执行
全文搜索 - 使用 FTS3,而不是
LIKE
可以在文本数据中进行更强大的搜索,并 以大幅加快结果的生成速度。请参阅 sqlite.org,用于 FTS3 和SQLiteDatabase
类以了解有关 Android 上的 SQLite 的信息。 - 如果您的数据是在线存储的,那么用户感知到的搜索效果
被用户的数据连接所禁止。您可能希望
进度指示器。请参阅
android.net
提供了网络 API 的参考信息ProgressBar
了解有关如何显示进度指示器的信息。
呈现结果
无论您的数据位于何处以及如何搜索,我们都建议您
您可以使用
Adapter
。这个
你可以在一个网页上显示所有搜索结果
RecyclerView
。
如果您的数据来自 SQLite 数据库查询,则可以将结果应用于
RecyclerView
(使用
CursorAdapter
。
如果您的数据采用其他格式,您可以创建
BaseAdapter
。
Adapter
将一组数据中的每一项绑定到
View
对象。时间
Adapter
会应用于 RecyclerView
,每个部分
数据会作为单独的视图插入列表中。“Adapter
”现为
一个接口,因此诸如此类的实现
CursorAdapter
- 用于绑定
Cursor
- 是
所需的资源。如果现有的实现方案都不适合您的数据,您可以
从 BaseAdapter
中实现您自己的自定义。
使用搜索对话框
搜索对话框在屏幕顶部提供了一个浮动搜索框, 应用图标位于屏幕左侧搜索对话框可以提供搜索建议 。当用户执行搜索时,系统会将搜索 传递给执行搜索的可搜索 Activity。
默认情况下,搜索对话框始终处于隐藏状态,直到用户将其激活。
您的应用可以通过调用
onSearchRequested()
。不过,只有在您完成上述操作后,
为 activity 启用搜索对话框。
要使搜索对话框能够执行搜索,请向系统指示
可搜索 Activity 必须从搜索对话框接收搜索查询。对于
请参阅上一部分中的示例,
创建一个可搜索的 activity,
已创建名为“SearchableActivity
”的 activity。如果您想
一个单独的 activity(例如名为 OtherActivity
的 activity),用于显示
搜索对话框,并将搜索传送到 SearchableActivity
,声明
在清单中指示 SearchableActivity
是可搜索 activity
供 OtherActivity
中的搜索对话框使用。
要为 Activity 的搜索对话框声明可搜索 Activity,请将
<meta-data>
元素(位于相应 activity 的
<activity>
元素。<meta-data>
元素必须包含 android:value
属性,用于指定
可搜索 activity 的类名称和 android:name
属性
值为 "android.app.default_searchable"
。
例如,下面是一个可搜索 Activity 的声明,
SearchableActivity
和另一个 activity,
OtherActivity
,它使用 SearchableActivity
来
执行搜索时执行的搜索:
<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>
由于 OtherActivity
现在包含
<meta-data>
元素,用于声明要将哪个可搜索 activity
用于搜索,则此 activity 会启用搜索对话框。尽管用户
在此 activity 中,onSearchRequested()
方法会激活
搜索对话框。当用户执行搜索时,系统会启动
SearchableActivity
,并提供ACTION_SEARCH
intent。
如果您希望应用中的每个 activity 都提供搜索对话框,请插入
前面的 <meta-data>
元素作为
<application>
元素,而不是每个 <activity>
。这样,每项活动
继承该值,提供搜索对话框,并将搜索传递给
相同的可搜索活动。如果您有多个可搜索的 activity,可以
替换默认的可搜索 activity,方法是将另一个
<meta-data>
声明。
现在为您的 activity 启用搜索对话框后,您的应用就可以 执行搜索。
调用搜索对话框
虽然某些设备提供了专用的搜索按钮,
按钮可能因设备而异,而且许多设备不提供搜索功能
按钮。因此,在使用搜索对话框时,您必须提供一个搜索按钮
在界面中通过调用以下函数激活搜索对话框:
onSearchRequested()
。
例如,在
选项菜单或界面布局
调用 onSearchRequested()
。
您还可以启用“输入搜索内容”该功能可启用
搜索对话框。按键为
插入搜索对话框。您可以在 activity 中启用“输入字词进行搜索”功能
通过调用
setDefaultKeyMode
- 或
DEFAULT_KEYS_SEARCH_LOCAL
:期间
您的活动记录
onCreate()
方法。
搜索对话框对 Activity 生命周期的影响
搜索对话框是
浮动的 Dialog
。它不会导致 activity 堆栈发生任何变化
没有生命周期方法,例如
onPause()
- 是
调用。您的 activity 会失去输入焦点,因为将输入焦点提供给
搜索对话框。
如果您希望在激活搜索对话框时收到通知,请替换
onSearchRequested()
方法结合使用。当系统调用此方法时,
表示您的 activity 失去了搜索对话框的输入焦点,因此
您可以执行任何适合该事件的操作,例如暂停游戏。除非
您将传递搜索上下文
(本文档的另一部分对此进行了讨论),使
方法是:
Kotlin
override fun onSearchRequested(): Boolean { pauseSomeStuff() return super.onSearchRequested() }
Java
@Override public boolean onSearchRequested() { pauseSomeStuff(); return super.onSearchRequested(); }
如果用户通过点按“返回”按钮取消搜索,则搜索对话框
并且 activity 会重新获得输入焦点。您可以注册以接收通知
搜索对话框关闭时
setOnDismissListener()
,
setOnCancelListener()
,
或者两者兼有您只需要注册
OnDismissListener
,
因为每次搜索对话框关闭时都会调用它。通过
OnCancelListener
仅适用于用户明确退出搜索对话框的事件,
它在执行搜索时不会被调用。在执行搜索时,
搜索对话框会自动消失。
如果当前 activity 不是可搜索 activity,则常规 activity
activity 生命周期事件会在用户执行
search - 当前 activity 会收到 onPause()
,如下文所述
简介
activity。不过,如果当前 activity 是可搜索 activity,
则会出现以下两种情况之一:
- 默认情况下,可搜索 Activity 会收到
带有
onCreate()
调用的ACTION_SEARCH
intent, 并且新 activity 实例会置于 activity 顶部 堆栈。现在,在 因此点按“返回”按钮会返回到上一个 可搜索 activity 实例,而不是退出可搜索 activity 活动。 - 如果您将
android:launchMode
设置为"singleTop"
, 那么可搜索 activity 会收到ACTION_SEARCH
intent ,其中包含以下电话号码:onNewIntent(Intent)
, 传递新的ACTION_SEARCH
intent。例如,以下是 您可以处理这种情况,即可搜索 activity 的启动模式 为"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); } }
与上一节中的示例代码相比, 执行搜索时,处理 搜索 intent 现在位于
handleIntent()
方法中,onCreate()
和onNewIntent()
可以执行它。当系统调用
onNewIntent(Intent)
时,activity 不会 因此getIntent()
方法返回的 intent 与通过onCreate()
接收的 intent 相同。 因此,您必须调用setIntent(Intent)
onNewIntent(Intent)
内:这样, 以后调用getIntent()
时,活动会更新。
第二种场景是使用 "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>
传递搜索上下文数据
在某些情况下,您可以对其中的搜索查询进行必要的优化
每次搜索的可搜索活动。不过,如果您希望优化
根据用户执行搜索的活动确定搜索条件。
搜索,您可以在系统发送到
您的可搜索活动记录您可以将其他数据
APP_DATA
Bundle
,
包含在 ACTION_SEARCH
intent 中。
如需将此类数据传递给可搜索 activity,请替换
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()
以激活搜索对话框。在用户之后
提交查询后,系统会将该查询连同数据一起传递到可搜索 Activity。
。您可以从 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); }
使用搜索微件
![显示应用顶部栏中的搜索视图的图片](https://developer.android.google.cn/static/images/ui/search-ui-topbar-33.png?authuser=9&hl=bg)
图 1. SearchView
widget
应用栏中的操作视图。
搜索微件提供的功能与搜索对话框相同。它 在用户执行搜索时启动相应的 Activity,并且它可以 提供搜索建议并执行语音搜索。如果无法选择 您将搜索微件放在应用栏中,也可以将搜索 widget 放置在 activity 布局中的某个位置。
<ph type="x-smartling-placeholder">配置搜索微件
创建
搜索配置和
可搜索的活动,启用辅助搜索
调用 SearchView
setSearchableInfo()
并将代表应用的 SearchableInfo
对象
可搜索配置。
您可以通过调用SearchableInfo
getSearchableInfo()
已开启
SearchManager
。
例如,如果您将 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; }
搜索微件现已配置完毕,系统会提供搜索查询 添加到可搜索的活动中。您还可以 搜索建议。
<ph type="x-smartling-placeholder">如需详细了解应用栏中的操作视图,请参阅 使用操作视图和操作 提供商。
搜索微件的其他功能
SearchView
widget 提供了一些其他功能,
可能想要:
- 提交按钮
- 默认情况下,系统没有提供用于提交搜索查询的按钮,因此用户必须
按键盘上的回车键启动搜索。您
可以添加“提交”按钮
setSubmitButtonEnabled(true)
。 - 搜索建议的查询优化
- 启用搜索建议后,您通常希望用户选择
但他们可能还需要优化建议的搜索查询
您可以在每条建议旁边添加一个按钮,用于插入该建议
,以便用户通过调用
setQueryRefinementEnabled(true)
。 - 能够切换搜索框的可见性
- 默认情况下,搜索微件会“图标化”也就是说
只能用一个搜索图标(放大镜)来表示。它会扩展为
在用户点按图标时显示搜索框。如上例所示
您可以通过调用
setIconifiedByDefault(false)
。 您还可以通过调用setIconified()
。
SearchView
类中还有其他几个 API
您可以自定义搜索微件。但其中的大多数选项
自行处理所有用户输入,而不是使用 Android 系统来提供
搜索查询并显示搜索建议。
同时使用 widget 和对话框
如果您将搜索微件作为
操作视图并启用
通过将它设置为在有空间的情况下显示在应用栏中
android:showAsAction="ifRoom"
,那么搜索 widget 可能会
不会显示为操作视图相反,菜单项可能会显示在溢出菜单中
菜单。例如,当您的应用在较小的屏幕上运行时
应用栏中有足够的空间来显示搜索微件以及其他操作
项或导航元素,使菜单项出现在溢出菜单中
菜单。放置在溢出菜单中后,该项将像普通菜单一样运作
项,并且不会显示操作视图(即搜索 widget)。
要处理这种情况,您需要附加搜索微件的菜单项
当用户从溢出菜单中选择搜索对话框时,必须激活该对话框。
为此,请实施
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
才能启用语音
搜索。第二个值 launchRecognizer
指定
语音搜索按钮必须启动一个识别器,用于返回
将转写文本发送到可搜索 activity。
您可以提供其他属性来指定语音搜索行为 例如预期的语言和要返回的结果数上限。请参阅 搜索配置参考,详细了解 了解可用属性的相关信息。
<ph type="x-smartling-placeholder">。添加搜索建议
搜索对话框和搜索微件都可以提供搜索建议 在 Android 系统的协助下由系统管理 建议列表,并在用户选择 建议。
您可以提供两种类型的搜索建议:
- 近期查询搜索建议
- 这些建议是用户以前用作搜索的字词 查询。请参阅添加 自定义搜索建议。
- 自定义搜索建议
- 这些是您通过自己的数据源提供的搜索建议, 帮助用户立即选择正确的拼写字词或搜索内容 。请参阅添加自定义搜索 建议。