目录

android搜索框实现

目录

android搜索框实现

在Map应用中会经常见到一个浮动的搜索框 一般可以搜索附近的POI点信息 而且这些功能基本都长得差不多 所以网上查了下原来在SDK 文档里就有 在Dev Guide中有详细的介绍 不过都是英文的 看了好久呢

功能是比较简单的 就是配置起来有点麻烦 下面详细说一下

首先看效果

http://hi.csdn.net/attachment/201104/22/0_1303441639UfnW.gif http://hi.csdn.net/attachment/201104/22/0_1303441643Az8c.gif

就这样简单 首先来看配置:

一、 搜索框配置文件 是一个用来配置您的应用程序中搜索框的设置的XML文件,这个文件一般命名为searchable.xml,并且保存在项目的res/xml/目录下。 配置文件的根节点必须为searchable,可以有一个或多个属性。

可以发现在SearchableInfo中 android是通过com.android.internal.R.styleable.Searchable 这个ID来获取这个配置文件的

这个Searchable应该就是标签的名字,所以必须这么命名,至于文件名不重要了 文档中说must besaved in the res/xml/ project directory 也就这个文件名不重要 但这个文件必须放在XML目录下 位置确定了 内容大该就是

    1. <

    searchable

    xmlns:android

  1. android:label

    “@string/searchLabel”

    android:hint

    “@string/searchHint”

  2. android:icon

    “@drawable/menu_route”

    android:searchSuggestAuthority

    “com.debby.googlemap.SuggestionProvider”

  3. android:queryAfterZeroResults

    “false”

    android:searchSuggestSelection

    " ? "

  4. </

    searchable

[xhtml]

  1. <

    searchable

    xmlns:android =“http://schemas. android .com/apk/res/android"android :label

    “@string/searchLabel”

    android:hint ="@string/searchHint” android

    :icon

    “@drawable/menu_route”

    android:searchSuggestAuthority =“com.debby.googlemap.SuggestionProvider” android

    :queryAfterZeroResults

    “false”

    android:searchSuggestSelection

    " ? "

    </

    searchable

其中有个 android:icon="@drawable/menu_route” 本来以为可以设置 就搜索Text前面那个View的 后来发现不起作用,而且文档中都没提到这个属性 看来确实没用啊 因为这属性我可折腾好久 这个以后再说吧

还有一点要注意的就是  android:label android:hint 属性不能直接写值 而是要points to a stringresource 就是用配置在values里的

android:label 标签不知道有啥用 不过还要有  android:hint 就是TextView为空的时候显示的值 相当于提示信息了

基本配置就这些 还有大量的配置是语音搜索的,不过估计这个功能真是不怎么常用吧 想要研究的就看文档吧 挺详细的 先看看吧

    1. <

    searchable

    xmlns:android

  1. android:label

    “string resource”

  2. android:hint

    “string resource”

  3. android:searchMode =[“queryRewriteFromData” | “queryRewriteFromText”]

  4. android:searchButtonText

    “string resource”

  5. android:inputType

    “inputType”

  6. android:imeOptions

    “imeOptions”

  7. android:searchSuggestAuthority

    “string”

  8. android:searchSuggestPath

    “string”

  9. android:searchSuggestSelection

    “string”

  10. android:searchSuggestIntentAction

    “string”

  11. android:searchSuggestIntentData

    “string”

  12. android:searchSuggestThreshold

    “int”

  13. android:includeInGlobalSearch =[“true” | “false”]

  14. android:searchSettingsDescription

    “string resource”

  15. android:queryAfterZeroResults =[“true” | “false”]

  16. android:voiceSearchMode =[“showVoiceSearchButton” | “launchWebSearch” | “launchRecognizer”]

  17. android:voiceLanguageModel =[“free-form” | “web_search”]

  18. android:voicePromptText

    “string resource”

  19. android:voiceLanguage

    “string”

  20. android:voiceMaxResults

    “int”

  21. <

    actionkey

  22. android:keycode

    “KEYCODE”

  23. android:queryActionMsg

    “string”

  24. android:suggestActionMsg

    “string”

  25. android:suggestActionMsgColumn

    “string”

  26. </

    searchable

[xhtml]

  1. <

    searchable

    xmlns:android

    android:label

    “string resource”

    android:hint

    “string resource”

    android:searchMode =[“queryRewriteFromData” | “queryRewriteFromText”] android:searchButtonText

    “string resource”

    android:inputType

    “inputType”

    android:imeOptions

    “imeOptions”

    android:searchSuggestAuthority

    “string”

    android:searchSuggestPath

    “string”

    android:searchSuggestSelection

    “string”

    android:searchSuggestIntentAction

    “string”

    android:searchSuggestIntentData

    “string”

    android:searchSuggestThreshold

    “int”

    android:includeInGlobalSearch =[“true” | “false”] android:searchSettingsDescription

    “string resource”

    android:queryAfterZeroResults =[“true” | “false”] android:voiceSearchMode =[“showVoiceSearchButton” | “launchWebSearch” | “launchRecognizer”] android:voiceLanguageModel =[“free-form” | “web_search”] android:voicePromptText

    “string resource”

    android:voiceLanguage

    “string”

    android:voiceMaxResults

    “int”

    <

    actionkey

    android:keycode

    “KEYCODE”

    android:queryActionMsg

    “string”

    android:suggestActionMsg

    “string”

    android:suggestActionMsgColumn

    “string”

    </

    searchable

二、 创建一个搜索功能的Activity

这里的Activity可以新建一个 当然也可以是当前弹出搜索框的Acitvity  这里我用到的MapAcitivity就是要显示搜索结果的 所以这里就直接用这个Acitivity了

那这两种方式实现差不多 不过也有点小小的差别 下面来看:

首先配是一样的 就是在Acitivity 标签中加入

  1. <action android:name= “android.intent.action.SEARCH” />
  2. <meta-data android:name= “android.app.searchable”
  3. android:resource= “@xml/searchable” />

[c-sharp]

  1.                <action android:name= “android.intent.action.SEARCH” />                    <meta-data android:name= “android.app.searchable” android:resource= “@xml/searchable” />

就可以了那这样的配置也就是只在这个Activity中可以使用搜索功能,其实Android的搜索框可以支持整个应用Application

这样就需要创建一个专门处理搜索的Acitivity 可以这样配置 需要在 这个标签下的

    1. <meta-data android:name= “android.app.default_searchable”
  1. android:value= “.MySearchableActivity” />

[c-sharp]

  1.     

三、 调用搜索框 现在已经配置完成了 下面就可以开始调用了

调用的方法很简单 所有的Acitivity都可以调用onSearchRequested() 方法 这样搜索框就出现了 ,那测试的时候可以有个简单的方法

在onCreate()方法中调用setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL),这样,当用户按下键盘上的按键时,将会自动激活搜索框

如果你要在执行搜索时,进行别的操作,可以重写onSearchRequested()方法 如下:

  1. @Override
  2. public boolean onSearchRequested() {
  3. //这个方法中干你想干的事
  4. doSometingOther();
  5. return super.onSearchRequested();
  6. }

[c-sharp]

  1. @Overridepublic boolean onSearchRequested() {

    //这个方法中干你想干的事    doSometingOther();    return super.onSearchRequested();}

还有如果我们想在调用的时候传递一些参数 也是可以的

  1. public boolean onSearchRequested() {

  2. Log.i(TAG, “onSearchRequested————========” );

  3. Bundle appData = new Bundle();

  4. appData.putString( “key” , “your info” );

  5. startSearch( null , true , appData, false );

  6. return

    true ;

  7. }

[c-sharp]

  1. public boolean onSearchRequested() {        Log.i(TAG, “onSearchRequested————========” );         Bundle appData = new Bundle();        appData.putString( “key” , “your info” );        startSearch( null , true , appData, false ); return

    true ;    }

四、 接受查询条件 并执行查询

如果是创建了专门处理查询的Acitivity 当然可以直接在onCreate中 执行查询操作

  1. @Override

  2. public

    void onCreate(Bundle savedInstanceState) {

  3. super.onCreate(savedInstanceState);

  4. setContentView(R.layout.search);

  5. Intent intent = getIntent();

  6. if (Intent.ACTION_SEARCH.equals(intent.getAction())) {

  7. String query = intent.getStringExtra(SearchManager.QUERY);

  8. doMySearch(query);

  9. }

  10. }

[c-sharp]

  1. @Overridepublic void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.search);    Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) {      String query = intent.getStringExtra(SearchManager.QUERY);      doMySearch(query);    }}

但如果是在当前的Acitivity上这样就不行了 应为onCreate就执行一次 这样就可以通过onNewIntent来实现了

  1. @Override

  2. public

    void onCreate(Bundle savedInstanceState) {

  3. super.onCreate(savedInstanceState);

  4. setContentView(R.layout.search);

  5. handleIntent(getIntent());

  6. }

  7. @Override

  8. protected

    void onNewIntent(Intent intent) {

  9. setIntent(intent);

  10. handleIntent(intent);

  11. }

  12. private

    void handleIntent(Intent intent) {

  13. if (Intent.ACTION_SEARCH.equals(intent.getAction())) {

  14. String query = intent.getStringExtra(SearchManager.QUERY);

  15. doMySearch(query);

  16. }

  17. }

[c-sharp]

  1. @Overridepublic void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.search);    handleIntent(getIntent());} @Overrideprotected void onNewIntent(Intent 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);    }}

这样就会通过doMySearch()完成了查询操作了 不过还有点需要注意 查询完成后我按返回发现还是这个Acitivity 不过是查询前的

这说明在Activity栈里有俩我的这个MapAcitivity实例 这个可以通过在Acitivity里android:launchMode=”singleTop”这样的配置解决

我的Acitivity配置是这样的

  1. <activity android:name= “.GoogleMapActivity” android:launchMode= “singleTop”
  2. android:label= “@string/app_name”
  3. <action android:name= “android.intent.action.MAIN” />
  4. <category android:name= “android.intent.category.LAUNCHER” />
  5. <action android:name= “android.intent.action.SEARCH” />
  6. <meta-data android:name= “android.app.searchable”
  7. android:resource= “@xml/searchable” />

[c-sharp]

  1. <activity android:name= “.GoogleMapActivity” android:launchMode= “singleTop” android:label= “@string/app_name”

                                <action android:name= “android.intent.action.MAIN” />                <category android:name= “android.intent.category.LAUNCHER” />                                         <action android:name= “android.intent.action.SEARCH” />                    <meta-data android:name= “android.app.searchable” android:resource= “@xml/searchable” />          

五、 纪录历史关键字 我们在查询完成后会希望保存这次查询的条件 甚至有的会连结果都保存了

android这里实现了保存关键字的功能 是通过SearchRecentSuggestionsProvider 来实现的

首先创建一个Provider类

  1. public

    class SearchSuggestionProvider extends SearchRecentSuggestionsProvider {

  2. /**

  3. * Authority

  4. */

  5. final static String AUTHORITY = “com.debby.googlemap.SuggestionProvider” ;

  6. /**

  7. * Mode

  8. */

  9. final static

    int MODE = DATABASE_MODE_QUERIES;

  10. public SearchSuggestionProvider() {

  11. super();

  12. setupSuggestions(AUTHORITY, MODE);

  13. }

  14. }

[c-sharp]

  1. public

    class SearchSuggestionProvider extends SearchRecentSuggestionsProvider { /**     * Authority     / final static String AUTHORITY = “com.debby.googlemap.SuggestionProvider” ; /*     * Mode     */ final static

    int MODE = DATABASE_MODE_QUERIES; public SearchSuggestionProvider() {        super();        setupSuggestions(AUTHORITY, MODE);    }}

当然还要在 Manifest中配置

<provider android:name=“com.debby.googlemap.SearchSuggestionProvider”

android:authorities=“com.debby.googlemap.SuggestionProvider” />

  1. <provider android:name= “com.debby.googlemap.SearchSuggestionProvider”
  2. android:authorities= “com.debby.googlemap.SuggestionProvider” />

[c-sharp]

  1. <provider android:name= “com.debby.googlemap.SearchSuggestionProvider” android:authorities= “com.debby.googlemap.SuggestionProvider” />

这里注意 android:authorities 的配置与Provider里的保持一致就好了

这样在Acitivity里就可以调用了

  1. SearchRecentSuggestions suggestions = new SearchRecentSuggestions( this ,
  2. SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);
  3. suggestions.saveRecentQuery(query, null );

[c-sharp]

  1. SearchRecentSuggestions suggestions = new SearchRecentSuggestions( this ,                SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);suggestions.saveRecentQuery(query, null );

保存完成了 点击搜索完成后保存成功了 下次搜索就可以看到 效果看PP

http://hi.csdn.net/attachment/201104/22/0_1303445467U5aM.gif

那有些时候需要保存一些查询结果 例如我在地图上查询一个地点位置 那我下次查询的时候希望可以快速实现查询

这种情况就可以把上次查询的一些该地点的信息 譬如 经纬度等信息保存下来 这样就直接通过sqlit来手动保存数据

可以在handleIntent()方法中进行插入 查询操作来完成了 就是个数据库操作 不再详细实现了

就到这了 继续研究Icon那个问题