android搜索框实现 【转】

来源:互联网 发布:老王python官网 编辑:程序博客网 时间:2024/06/08 02:11
 

 

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

 

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

 

首先看效果

 

 

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

 

一、搜索框配置文件是一个用来配置您的应用程序中搜索框的设置的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目录下位置确定了 内容大该就是

view plainprint?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <searchable xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:label="@string/searchLabel" android:hint="@string/searchHint"  
  4.     android:icon="@drawable/menu_route" android:searchSuggestAuthority="com.debby.googlemap.SuggestionProvider"  
  5.     android:queryAfterZeroResults="false" android:searchSuggestSelection=">  
  6. </searchable>  
[xhtml] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?><searchable xmlns:android="http://schemas.android.com/apk/res/android"android:label="@string/searchLabel" androidandroid:hint="@string/searchHint"android:icon="@drawable/menu_route" androidandroid: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为空的时候显示的值 相当于提示信息了

 

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

 

view plainprint?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <searchable xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:label="string resource"  
  4.     android:hint="string resource"  
  5.     android:searchMode=["queryRewriteFromData" "queryRewriteFromText"]  
  6.     android:searchButtonText="string resource"  
  7.     android:inputType="inputType"  
  8.     android:imeOptions="imeOptions"  
  9.     android:searchSuggestAuthority="string"  
  10.     android:searchSuggestPath="string"  
  11.     android:searchSuggestSelection="string"  
  12.     android:searchSuggestIntentAction="string"  
  13.     android:searchSuggestIntentData="string"  
  14.     android:searchSuggestThreshold="int"  
  15.     android:includeInGlobalSearch=["true" "false"]  
  16.     android:searchSettingsDescription="string resource"  
  17.     android:queryAfterZeroResults=["true" "false"]  
  18.     android:voiceSearchMode=["showVoiceSearchButton" "launchWebSearch" "launchRecognizer"]  
  19.     android:voiceLanguageModel=["free-form" "web_search"]  
  20.     android:voicePromptText="string resource"  
  21.     android:voiceLanguage="string"  
  22.     android:voiceMaxResults="int"  
  23.     >  
  24.     <actionkey  
  25.         android:keycode="KEYCODE"  
  26.         android:queryActionMsg="string"  
  27.         android:suggestActionMsg="string"  
  28.         android:suggestActionMsgColumn="string" >  
  29. </searchable>  
[xhtml] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>    <searchable xmlns:android="http://schemas.android.com/apk/res/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 标签中加入

view plainprint?
  1. <intent-filter>    
  2.                 <action android:name="android.intent.action.SEARCH" />    
  3.             </intent-filter>    
  4.             <meta-data android:name="android.app.searchable"    
  5.                        android:resource="@xml/searchable"/>   
[c-sharp] view plaincopyprint?
  1. <intent-filter>               <action android:name="android.intent.action.SEARCH" />          </intent-filter>          <meta-data android:name="android.app.searchable"                     android:resource="@xml/searchable"/>   

 

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

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

view plainprint?
  1. <!-- declare the default searchable Activity for the whole app -->  
  2.    <meta-data android:name="android.app.default_searchable"  
  3.               android:value=".MySearchableActivity" />  
[c-sharp] view plaincopyprint?
  1. <!-- declare the default searchable Activity for the whole app -->    <meta-data android:name="android.app.default_searchable"               android:value=".MySearchableActivity" />  

 

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

 

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

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

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

view plainprint?
  1. @Override  
  2. public boolean onSearchRequested()  
  3. //这个方法中干你想干的事  
  4.     doSometingOther();  
  5.     return super.onSearchRequested();  
  6.  
[c-sharp] view plaincopyprint?
  1. @Overridepublic boolean onSearchRequested() {//这个方法中干你想干的事    doSometingOther();    return super.onSearchRequested();}  

 

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

 

view plainprint?
  1. public boolean onSearchRequested()  
  2.         Log.i(TAG,"onSearchRequested------------========");    
  3.         Bundle appData new Bundle();  
  4.         appData.putString("key""your info");  
  5.         startSearch(nulltrueappData, false);    
  6.         return true 
  7.      
[c-sharp] view plaincopyprint?
  1. public boolean onSearchRequested()        Log.i(TAG,"onSearchRequested------------========");         Bundle appData new Bundle();        appData.putString("key""your info");        startSearch(nulltrueappData, false);          return true    

 

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

 

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

view plainprint?
  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] view plaincopyprint?
  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来实现了

view plainprint?
  1. @Override  
  2. public void onCreate(Bundle savedInstanceState)  
  3.     super.onCreate(savedInstanceState);  
  4.     setContentView(R.layout.search);  
  5.     handleIntent(getIntent());  
  6.  
  7.    
  8. @Override  
  9. protected void onNewIntent(Intent intent)  
  10.     setIntent(intent);  
  11.     handleIntent(intent);  
  12.  
  13.    
  14. private void handleIntent(Intent intent)  
  15.     if (Intent.ACTION_SEARCH.equals(intent.getAction()))  
  16.       String query intent.getStringExtra(SearchManager.QUERY);  
  17.       doMySearch(query);  
  18.      
  19.  
[c-sharp] view plaincopyprint?
  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配置是这样的

 

view plainprint?
  1. <activity android:name=".GoogleMapActivity" android:launchMode="singleTop"  
  2.                   android:label="@string/app_name" 
  3.             <intent-filter>  
  4.                 <action android:name="android.intent.action.MAIN" />  
  5.                 <category android:name="android.intent.category.LAUNCHER" />  
  6.             </intent-filter>  
  7.             <intent-filter>    
  8.                 <action android:name="android.intent.action.SEARCH" />    
  9.             </intent-filter>    
  10.             <meta-data android:name="android.app.searchable"    
  11.                        android:resource="@xml/searchable"/>    
  12.         </activity>  
[c-sharp] view plaincopyprint?
  1. <activity android:name=".GoogleMapActivity" android:launchMode="singleTop"                  android:label="@string/app_name"           <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>            <intent-filter>                 <action android:name="android.intent.action.SEARCH" />          </intent-filter>          <meta-data android:name="android.app.searchable"                     android:resource="@xml/searchable"/>          </activity>  

 

 

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

 

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

 

首先创建一个Provider类

 

view plainprint?
  1. public class SearchSuggestionProvider extends SearchRecentSuggestionsProvider  
  2.       
  3.     final static String AUTHORITY "com.debby.googlemap.SuggestionProvider" 
  4.       
  5.     final static int MODE DATABASE_MODE_QUERIES;  
  6.     public SearchSuggestionProvider()  
  7.         super();  
  8.         setupSuggestions(AUTHORITY, MODE);  
  9.      
  10.  
[c-sharp] view plaincopyprint?
  1. public class SearchSuggestionProvider extends SearchRecentSuggestionsProvider        final static String AUTHORITY "com.debby.googlemap.SuggestionProvider"       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" />

view plainprint?
  1. <provider android:name="com.debby.googlemap.SearchSuggestionProvider"  
  2.             android:authorities="com.debby.googlemap.SuggestionProvider" />  
[c-sharp] view plaincopyprint?
  1. <provider android:name="com.debby.googlemap.SearchSuggestionProvider"            android:authorities="com.debby.googlemap.SuggestionProvider" />  

 

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

 

这样在Acitivity里就可以调用了

 

 

view plainprint?
  1. SearchRecentSuggestions suggestions new SearchRecentSuggestions(this 
  2.                 SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);  
  3. suggestions.saveRecentQuery(query, null);  
[c-sharp] view plaincopyprint?
  1. SearchRecentSuggestions suggestions new SearchRecentSuggestions(this               SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);suggestions.saveRecentQuery(query, null);  

 

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

 

 

 

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


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

 

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

 

就到这了继续研究Icon那个问题
原创粉丝点击