android搜索框實現
在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目錄下 位置確定了 內容大該就是
- <?xmlversion="1.0"encoding="utf-8"?>
- <searchablexmlns: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>
- <?xmlversion="1.0"encoding="utf-8"?><searchablexmlns: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為空的時候顯示的值 相當於提示信息了
基本配置就這些 還有大量的配置是語音搜索的,不過估計這個功能真是不怎么常用吧 想要研究的就看文檔吧 挺詳細的 先看看吧
- <?xmlversion="1.0"encoding="utf-8"?>
- <searchablexmlns: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>
- <?xmlversion="1.0"encoding="utf-8"?> <searchablexmlns: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 標簽中加入
- <intent-filter>
- <action android:name="android.intent.action.SEARCH" />
- </intent-filter>
- <meta-data android:name="android.app.searchable"
- android:resource="@xml/searchable"/>
- <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> 這個標簽下的
- <!-- declare the default searchable Activity for the whole app -->
- <meta-data android:name="android.app.default_searchable"
- android:value=".MySearchableActivity" />
- <!-- 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()方法 如下:
- @Override
- public boolean onSearchRequested() {
- //這個方法中干你想干的事
- doSometingOther();
- return super.onSearchRequested();
- }
- @Overridepublic boolean onSearchRequested() {//這個方法中干你想干的事 doSometingOther(); return super.onSearchRequested();}
還有如果我們想在調用的時候傳遞一些參數 也是可以的
- public boolean onSearchRequested() {
- Log.i(TAG,"onSearchRequested------------========");
- Bundle appData = new Bundle();
- appData.putString("key", "your info");
- startSearch(null, true, appData, false);
- returntrue;
- }
- public boolean onSearchRequested() { Log.i(TAG,"onSearchRequested------------========"); Bundle appData = new Bundle(); appData.putString("key", "your info"); startSearch(null, true, appData, false); returntrue; }
四、接受查詢條件 並執行查詢
如果是創建了專門處理查詢的Acitivity 當然可以直接在onCreate中 執行查詢操作
- @Override
- publicvoid 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);
- }
- }
- @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來實現了
- @Override
- publicvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.search);
- handleIntent(getIntent());
- }
- @Override
- protectedvoid onNewIntent(Intent intent) {
- setIntent(intent);
- handleIntent(intent);
- }
- privatevoid handleIntent(Intent intent) {
- if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
- String query = intent.getStringExtra(SearchManager.QUERY);
- doMySearch(query);
- }
- }
- @Overridepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search); handleIntent(getIntent());} @Overrideprotected void onNewIntent(Intent intent) { setIntent(intent); handleIntent(intent);} privatevoid 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配置是這樣的
- <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>
- <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類
- publicclass SearchSuggestionProvider extends SearchRecentSuggestionsProvider {
- /**
- * Authority
- */
- final static String AUTHORITY = "com.debby.googlemap.SuggestionProvider";
- /**
- * Mode
- */
- final staticint MODE = DATABASE_MODE_QUERIES;
- public SearchSuggestionProvider() {
- super();
- setupSuggestions(AUTHORITY, MODE);
- }
- }
- publicclass SearchSuggestionProvider extends SearchRecentSuggestionsProvider { /** * Authority */ final static String AUTHORITY = "com.debby.googlemap.SuggestionProvider"; /** * Mode */ final staticint MODE = DATABASE_MODE_QUERIES; public SearchSuggestionProvider() { super(); setupSuggestions(AUTHORITY, MODE); }}
當然還要在 Manifest中配置
<provider android:name="com.debby.googlemap.SearchSuggestionProvider" android:authorities="com.debby.googlemap.SuggestionProvider" />
- <provider android:name="com.debby.googlemap.SearchSuggestionProvider"
- android:authorities="com.debby.googlemap.SuggestionProvider" />
- <provider android:name="com.debby.googlemap.SearchSuggestionProvider" android:authorities="com.debby.googlemap.SuggestionProvider" />
這里注意 android:authorities 的配置與Provider里的保持一致就好了
這樣在Acitivity里就可以調用了
- SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
- SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);
- suggestions.saveRecentQuery(query, null);
- SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);suggestions.saveRecentQuery(query, null);
保存完成了 點擊搜索完成后保存成功了 下次搜索就可以看到 效果看PP
那有些時候需要保存一些查詢結果 例如我在地圖上查詢一個地點位置 那我下次查詢的時候希望可以快速實現查詢
這種情況就可以把上次查詢的一些該地點的信息 譬如 經緯度等信息保存下來 這樣就直接通過sqlit來手動保存數據
可以在handleIntent()方法中進行插入 查詢操作來完成了 就是個數據庫操作 不再詳細實現了
就到這了 繼續研究Icon那個問題