Android系统搜索框架实战:创建第一个搜索接口

2016-03-16 16:04 阅读 8,706 次 评论 2 条
目录:

  • 摘要
  • 基础介绍
  • 配置查询的xml文件
  • 创建处理查询的activity
    manifest声明查询的activity
    执行查询操作

摘要

当你准备添加一个搜索功能到你的应用中时,Android通过使用search dialog或search widget帮你实现用户接口,search dialog和search widget两种方式都可以发送用户的查询数据到指定的activity,使用其中一种方式,在activity可能调用search dialog或search widget中初始化搜索对象,系统会启动合适的activity执行搜索并展示结果。

基础介绍

在开始开发搜索功能之前,你应该确定是使用search dialog实现搜索功能还是使用search widget,这两种方式提供的搜索功能稍微有点区别:

  • search dialog是一个系统控件,当被用户激活时,search dialog出现在activity的顶部位置,如图 1。

    Android系统控制着search dialog的所有事件,当用户提交查询,系统发送查询的内容到指定的activity处理搜索功能,同时配置好搜索提示

  • search widgetSearchView实例对象,你可以放置在布局文件的任意位置。默认,search widget外观和EditText一样,但你可以通过配置search widget以便系统处理所有输入事件,并发送查询内容到指定的activity,同时也可以配置搜索提示。然而,search widget只在Android 3.0(API 11)系统之上可用

001-create a search interface

PS:如果你想要处理自定义处理所有的search widget输入,可以使用各种回调方法和监听器。可以参考《SearchView

当用户执行一个来自search dialog或search widget的搜索时,系统会创建一个Intent并需要查询的内容保存在里面,然后系统启动被声明来处理查询的activity(searchable activity)和发送intent给它。查询助手的开发步骤:

  • 配置查询的XML文件
  • 创建处理查询的activity
  • 指定查询接口:search dialog或search widget

配置查询的XML文件

在res根目录下创建文件夹xml(例如:res/xml/),然后新建一个xml文件,命名searchable.xml并保存在xml文件夹中,xml文件代码如下:

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

android:label是唯一需要的属性,它指向一个字符串资源,该字符串是应用程序的名字。该标签实际上是不可见的,除非你开启了提示查询功能。那时,该标签会显示在系统配置的查询列表中。

android:hint属性虽说不是必须的,但还建议添加,因为它将会提示用户正确输入查询内容。

元素还可以添加额外的属性,根据需要添加。

创建处理查询的activity

处理查询的activity接收用户输入的信息执行查询并展示结果。在使用search dialog或search widget执行查询时,系统会使用添加ACTION_SEARCH action的Intent启动处理查询的activity,代码如下:

  1. if (Intent.ACTION_SEARCH.equals(intent.getAction())) {  
  2.             String query = intent.getStringExtra(SearchManager.QUERY);  
  3.              SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,  
  4.                         MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);  
  5.                 suggestions.saveRecentQuery(query, null);  
  6.             doMySearch(query);  
  7.         }  

manifest声明查询的activity

在manifest文件中添加如下代码:

  1. <application ... >  
  2.     <activity android:name=".SearchableActivity" >  
  3.         <intent-filter>  
  4.             <action android:name="android.intent.action.SEARCH" />  
  5.         </intent-filter>  
  6.         <meta-data android:name="android.app.searchable"  
  7.                    android:resource="@xml/searchable"/>  
  8.     </activity>  
  9.     ...  
  10. </application>  

元素必须包括android:name属性值“android.app.searchable”、android.resource属性值res/xml/searchable.xml

PS:上述不需要添加默认的值,因为系统发送明确发送的ACTION_SEARCH到指定的searchable activity,使用组件的名字。

执行查询操作

一旦你在manifest文件中声明了你的searchable activity,在searchable activity执行查询的三个步骤:

  • 接收查询字符串
  • 执行查询操作
  • 展示查询结果

接收查询字符串

当用户执行search dialog或search widget查询时,系统启动searchable activity并将ACTION_SEARCH intent发送给它,intent携带着用户输入的查询内容,在启动searchable activity时可以检查intent并提取查询内容,具体代码如下:

  1. @Override  
  2. public void onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     setContentView(R.layout.search);  
  5.   
  6.     // Get the intent, verify the action and get the query  
  7.     Intent intent = getIntent();  
  8.     if (Intent.ACTION_SEARCH.equals(intent.getAction())) {  
  9.       String query = intent.getStringExtra(SearchManager.QUERY);  
  10.       doMySearch(query);  
  11.     }  
  12. }  

查询内容字符串被存储在ACTION_SEARCH intent里面,获取查询内容并在doMySearch()方法中操作

执行查询操作

存储和查询数据的操作在应用程序中是独立的,你可以使用很多种方式来存储和查询你的数据,这里是你可能需要应用的几个小步骤:

  • 如果你的数据保存在SQLite数据库中,进行全文搜索(使用FTS3,而不是一个LIKE查询)可提供跨文本数据的更强大的搜索,可以更快地显著产生结果
  • 如果你的数据存储在网络上,你需要显示一个进度条直到获取返回的数据,推荐阅读《Android开发之ProgressDialog读取文件进度解析》

不管你的数据存储在哪来和怎么获取查询的内容,我们建议使用适配器将结果返回到searchable activity中,然后可以简单使用ListView呈现结果内容,如果查询的内容来自SQLite数据库,使用的是CursorAdapter适配器,如果你的数据来自其它格式类型,你可以使用BaseAdapter。

展示查询结果

正如上一步所说的,查询内容需要在列表中展示,所以让searchable activity继承ListActivity,然后使用内部方法setListAdapter()传入绑定数据的Adapter对象即可。

指定查询接口:search dialog或search widget

search dialog和search widget在显示界面上有所区别,并在接口查询的activity调用方法不一样,关键代码如下:

  1. private void searchView(int id) {  
  2.         switch (id) {  
  3.         case SEARCH_DIALOG:  
  4.   
  5.             mEditText = (EditText) findViewById(R.id.input_content);  
  6.             mEditText.setOnClickListener(new View.OnClickListener() {  
  7.   
  8.                 @Override  
  9.                 public void onClick(View v) {  
  10.                     onSearchRequested();  
  11.   
  12.                 }  
  13.             });  
  14.             break;  
  15.   
  16.         case SEARCH_WIDGET:  
  17.   
  18.             SearchView mSearchView = (SearchView) findViewById(R.id.searchView1);  
  19.             SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);  
  20.             mSearchView.setSearchableInfo(searchManager  
  21.                     .getSearchableInfo(getComponentName()));  
  22.             mSearchView.setIconifiedByDefault(false);  
  23.               
  24.             break;  
  25.         }  
  26.   
  27.     }  

你可能感兴趣的文章

来源:TeachCourse每周一次,深入学习Android教程,关注(QQ158#9359$239或公众号TeachCourse)
转载请注明出处: https://www.teachcourse.cn/1569.html ,谢谢支持!

资源分享

Android面试笔记二:果肉教育 Android面试笔记二:果肉教育
十一种错误的避孕观念 十一种错误的避孕观念
关于universal-image-loader如何防止Bitmap OOM的说明 关于universal-image-loader如何
三级缓存的含义和如何实战使用? 三级缓存的含义和如何实战使用?