【Android开发】完善搜索功能-添加最近查询字段
原文:http://android.eoe.cn/topic/summary
本文内容
-
基础知识|基础知识*
-
创建一个内容提供者|创建一个内容提供者*
-
修改搜索配置|修改搜索配置*
-
保存查询|保存查询*
-
清除建议项数据|清除建议项数据*
关键类
SearchRecentSuggestions
SearchRecentSuggestionsProvider
参考
Searchable Configuration
http://developer.android.com/images/search/search-suggest-recent-queries.png
图1。搜索对话框的截图,该对话框带有最近搜索建议项。
当使用Android搜索对话框或者搜索小工具时,你可以提供基于最近搜索查询的搜索建议项。举个例子,如果一个用户之前搜索过 "puppies,"那么一旦他或她开始键入同一个查询的时候这个查询将作为一个建议项展示出来。图1展示了一个带有最近查询建议项的搜索对话框的例子。
在你开始这么做之前,你需要在你的应用中为基本的搜索实现搜索对话框或者一个搜索小工具。如果你还没有实现,请看Creating a Search Interface。
* 基础知识*
最近搜索建议项只是被保存下来的搜索。当用户选择了其中一个建议项,你的搜索Activity会收到一个带有该Activity已经处理过的搜索查询的ACTION_SEARCH意图(如在Creating a Search Interface描述的那样)。
要提供搜索建议项,你需要:
* 实现一个搜索的Activity,如在Creating a Search Interface描述的那样。
* 创建一个继承自SearchRecentSuggestionsProvider的内容提供者并在你的应用清单中声明它。
* 修改搜索配置中有关提供搜索建议项的内容提供者的信息。
* 每次搜索执行的时候把查询内容保存到你的内容提供者中。
正如Android系统显示搜索对话框那样,它也同样在对话框或者搜索小工具下显示搜索建议项。你所需要做的是提供一个系统能从中取得建议项的源。
当系统识别到你的Activity是用于搜索的并且提供了搜索建议项,一旦用户开始键入查询的时候以下步骤就会发生:
* 系统取得搜索查询文本(不管当前键入了什么)并对包含你搜索建议项的内容提供者进行一次查询。
* 你的内容提供者返回一个Cursor,该Cursor指向所有与查询文本匹配的搜索建议项。
* 系统以列表形式展现该Cursor提供的建议项。
一旦最近搜索建议项展示出来,以下事情可能会发生:
如果用户键入了另外一个关键字,或者以任何形式改变了查询内容,系统将会重复上述步骤并更新搜索建议项列表。
如果用户执行了搜索,这些建议项将会被忽略,并且系统会使用一般的ACTION_SEARCH意图将该搜索传递到你的搜索Activity中。
如果用户选择了其中一个建议项,一个ACTION_SEARCH意图将会被传递到你的搜索Activity中,使用被选中的建议文本作为查询。
你的内容提供者继承的SearchRecentSuggestionsProvider类自动地完成了上述的工作,所以实际上只有很少的代码需要你去编写。
* 创建一个内容提供者*
为了最近搜索建议项你所需的那个内容提供者必须是SearchRecentSuggestionsProvider的一个实现。这个类几乎为了做了所有的事情。你所需要做的只是写一个执行一行代码的类构造器。
举个例子,这是一个作为最近搜索建议项的内容提供者的一个完整的实现。
public class MySuggestionProvider extends SearchRecentSuggestionsProvider {
public final static String AUTHORITY = "com.example.MySuggestionProvider";
public final static int MODE = DATABASE_MODE_QUERIES;
1 2 3 |
public MySuggestionProvider() {
setupSuggestions(AUTHORITY, MODE);
}
|
}
setupSuggestions())方法的调用传递了搜索鉴权的名字和数据库模式。搜索鉴权可以是任何独特的字符串,但最好的做法是使用你内容提供者的全路径(提供者的类名跟随在包名后面;举个例子,“com.example.MySuggestionProvider”)。数据库模式必须包含DATABASE_MODE_QUERIES并可以选择性的包含DATABASE_MODE_2LINES,这个模式在你的建议项表中增加了另一列,允许你为每个建议项提供第二行文本。举个例子,如果你想为每个建议项提供两行文本:
public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;
现在在你的应用程序清单中使用与你SearchRecentSuggestionsProvider类(和搜索配置)中同样的鉴权字符串来声明你的内容提供者。举例:
...
* 修改搜索配置*
要配置的让系统去使用你的建议项提供者,你需要在你搜索配置的 android:searchSuggestAuthority 和 android:searchSuggestSelection 属性。举个例子:
<?xml version"utf-8"?>
AUTHORITY字符串)。
" ?"),这是SQLite选择参数的一个简单的占位符(会被用户输入的查询文本自动替换)。
* 保存查询*
要填充你的最近查询的集合,添加每个你搜索Activity接收到的查询到你的SearchRecentSuggestionsProvider中。要做这个事情,每次你的搜索Activity接收到一个查询的时候创建一个SearchRecentSuggestions的实例并调用saveRecentQuery())。举个例子,这里展示了你可以怎样在你搜索Activity的onCreate())方法期间保存查询。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
1 2 3 4 5 6 7 8 |
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);
suggestions.saveRecentQuery(query, null);
}
|
}
SearchRecentSuggestionsProvider构造函数需要与你在内容提供者中声明的一样的鉴权和数据库模式。
saveRecentQuery())取搜索查询字符串作为第一个参数并可选的用第二个参数来包含建议项的第二行数据(或者空)。第二个参数仅在你用DATABASE_MODE_2LINES来为你的搜索建议项启用双行模式的情况下使用。如果你启用了双行模式,那么当系统在寻找匹配的建议项时,这个第二行也会被用作查询文本的匹配。
* 清除建议项数据*
为了保护用户的隐私,你应该总是提供一个方法给用户清楚最近搜索建议项。要清楚查询历史,调用clearHistory())。举个例子:
SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE);
suggestions.clearHistory();
选择一个“清除搜索历史”的菜单项或设置项或按钮来执行这段代码。你也应该提供一个确认对话框来确认用户是否真要删除他们的搜索历史。