當您需要在您的應用程式中提供搜尋服務時,您第一個想到的是您的搜尋方塊要放哪呢?通過使用Android的搜尋方塊架,應用程式將顯示一個自訂搜尋對話方塊
來處理使用者的搜尋請求。通過一個簡單的搜尋按鈕或從您的應用程式中調用API,搜尋對話方塊就會顯示在螢幕的頂部,並會自動顯示您的應用程式圖示。如所
示:
本文將教你如何為你的應用程式提供一個自訂搜尋對話方塊。這樣做,給您的使用者提供一個標準化的搜尋體驗,並能增加如語音搜尋和搜尋建議等功能。
基礎知識
Android的搜尋方塊架將代您管理的搜尋對話方塊,您不需要自己去開發一個搜尋方塊,不需要擔心要把搜尋方塊放什麼位置,也不需要擔心搜尋方塊影響您當前的界
面。所有的這些工作都由SearchManager類來為您處理(以下簡稱“搜尋管理器”),它管理的Android搜尋對話方塊的整個生命週期,並執行您
的應用程式將發送的搜尋請求,返回相應的搜尋索引鍵。
當使用者執行一個搜尋,搜尋管理器將使用一個專門的Intent把搜尋查詢的關鍵字傳給您在設定檔中配置的處理搜尋結果的Activity。從本質上講,
所有你需要的就是一個Activity來接收Intent,然後執行搜尋,並給出結果。具體來說,你需要的做的事就包括以下內容:
一個搜尋配置
我們用個XML設定檔來對搜尋對話方塊進行配置,包括一些功能的配置,如文字框,設定語音搜尋和搜尋建議中顯示的提示文字等。
一個用來處理搜尋請求的Activity
這個Activity用來接收搜尋查詢的內容,然後搜尋您的資料並顯示搜尋結果。
一種使用者執行搜尋的途徑
預設情況下,一旦你配置了一個可搜尋的Activity,裝置搜尋鍵(如果有)將調用搜尋對話方塊。然而,你應該始終提供另一種手段,讓使用者可以調用搜尋對話方塊,如在選項菜單中的搜尋按鈕或其他使用者介面上的按鈕,因為不是所有的裝置提供一個專門的搜尋鍵。
建立一個搜尋對話方塊設定檔
搜尋方塊設定檔是一個用來配置您的應用程式中搜尋方塊的設定的XML檔案,這個檔案一般命名為searchable.xml,並且必須儲存在項目的res/xml/目錄下。
設定檔的根節點必須為,可以有一個或多個屬性。如所示:
<searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/search_label" android:searchSettingsDescription="@string/settings_description" android:includeInGlobalSearch="true" android:searchSuggestAuthority="dictionary" android:searchSuggestIntentAction="android.intent.action.VIEW"></searchable>
上面的設定檔中,除android:hint屬性外,其它都是一個搜尋對話方塊必須的配置項,android:label是一個必須的屬性,它的值
為一個string資源引用,不能直接用字串,通常會是應用程式的名稱(儘管它是一個必須的屬性,但通常情況下是不顯示出來的,除非你開啟了搜尋建議功
能)。android:hint是配置搜尋方塊的輸入提示資訊,也必須引用string.xml中配置的字串資源,不能直接使用字串。
可以配置很多的屬性,但大部分屬性都只是在使用搜尋建議和語音搜尋時進行配置,儘管如此,我們建議你一定要配置android:hint,用於提示使用者需要輸入的資訊。 includeInGlobalSearch ?
android:searchSuggestAuthority 搜尋建議其與Provider的
android:authorities要一致,才能通過provider的query進行動態關聯資料
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {},
android:searchSuggestIntentAction 當使用者點擊關聯搜尋加過資料時,產生的Action動作. 其會建立搜尋響應Activity並包含一個
android.intent.action.VIEW動作。
接下來,你需要把這個設定檔放到你的應用程式中。
Provider 配置
<!-- Provides search suggestions for words and their definitions. -->
<provider android:name="DictionaryProvider"
android:authorities="dictionary"
android:syncable="false" />
建立一個可用於搜尋的Activity
當使用者從一個搜尋方塊執行搜尋時,搜尋管理器(Search Manager)會通過ACTION_SEARCH Intent 把要搜尋的內容(關鍵字)發送到一個可執行搜尋的Activity。這個Acitivity查詢資料並顯示結果。
定義一個可搜尋的Activity
如果你還沒有準備好,那麼就建立一個用來執行搜尋的Activity,聲明它可以響應ACTION_SEARCH Intent ,並且增加搜尋方塊配置資訊。為此,你需要添加一個元素和一個元素在你的manifest檔案中的節點。如下所示:
<application ... > <activity android:name=".MySearchableActivity" > <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/> </activity> ...</application
中的android:name屬性值必須為”android.app.searchable”,android:resource屬性值必須引用上面提到的res/xml/目錄下的搜尋設定檔(本例中的res/xml/searchable.xml)。 在改Activity下點擊搜尋方塊時會載入searchable.xml顯示
請注意,只有配置了上面的meta-data節點的Activity的節點才能執行搜尋,如果想在整個應用程式中都可以調用搜尋方塊,可以進行如下配置:<application ... ><br /> <activity android:name=".MySearchableActivity" ><br /> <intent-filter><br /> <action android:name="android.intent.action.SEARCH" /><br /> </intent-filter><br /> <meta-data android:name="android.app.searchable"<br /> android:resource="@xml/searchable"/><br /> </activity><br /> <activity android:name=".AnotherActivity" ... ><br /> </activity><br /> <!—這個配置就可以讓你在整個應用程式中調用搜尋方塊 --><br /> <meta-data android:name="android.app.default_searchable"<br /> android:value=".MySearchableActivity" /><br /> ...<br /></application>
上面代碼中android:name=”android.app.default_searchable”
定義一個響應搜尋方塊搜尋請求的名稱,android:value指定是由哪個Activity響應並執行搜尋。當我們在應用程式中的
OtherAcitivity中執行搜尋請求時,MySearchableActivity將會被載入用於執行搜尋並顯示搜尋結果。
執行一個搜尋
當一個Activity聲明為可搜尋時,執行實際的搜尋包括三個步驟:接收查詢,檢索你的資料,並提交結果。
通常情況下,你的搜尋結果需要在一個ListView中展現,所以你用於執行搜尋的Acitivity要繼承ListActivity,這樣,可以方便的訪問ListView的Api。
接收搜尋查詢
當從搜尋對話方塊執行搜尋時,剛才配置的可用於搜尋的Acitivity將會被Intent啟用,同時帶著一些搜尋相關的參數,你需要檢查Intent並做出搜尋響應,如下所示:
@Override
public 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);
}else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
// from click on search results
Dictionary.getInstance().ensureLoaded(getResources());
String word = intent.getDataString();
Dictionary.Word theWord = Dictionary.getInstance().getMatches(word).get(0);
launchWord(theWord);
finish();
}
}
if (Intent.ACTION_VIEW.equals(intent.getAction())) 即搜尋下點擊提示Item時的Action處理邏輯。
doMySearch()方法將根據關鍵字查詢資料庫,或從網路上查詢資料,如果是耗時的搜尋,你還需要使用進度條,來告訴使用者搜尋進行中,最後返回結果後,可以調用ListView的setAdapter()方法將結果顯示在ListView中。
調用搜尋對話方塊
你可以從應用程式中的任何一個地方調用onSearchRequested()方法啟用搜尋方塊,比如從菜單中或者一個按鈕等。你也要以在
onCreate()方法中調用setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL),這樣,當使用者按下鍵盤上的
按鍵時,將會自動啟用搜尋方塊。
搜尋方塊和普通對話方塊一樣,浮動在螢幕的最上方,它不會改變任何Activity堆棧狀態,沒有任何Activity生命週期中的方法會被調用,只是當搜尋方塊出現就,正在啟動並執行Activity會失去輸入焦點。
如果你要在執行搜尋時,進行別的操作,可以重寫onSearchRequested()方法,如下所示:
@Overridepublic boolean onSearchRequested() {//這個方法中幹你想乾的事,比如做一些被始化工作 pauseSomeStuff(); return super.onSearchRequested();}
如果當前的Activity就是響應搜尋請求的Activity時,會有以下兩種情況:
預設情況下,ACTION_SEARCH
Intent將會建立一個新的Activity,並調用onCreate()方法,這個新的Activity會顯示在最前面,你將同時有兩個
Activity執行個體。當你按“返回”鍵裡,會回到沒有執行搜尋前的一個Activity。
另一種情況是配置了android:launchMode=”singleTop”的Activity,這時,我們需要
在 onNewIntent(Intent)方法中處理搜尋請求,如下所示:
@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); }}
相應的Activity配置如下
<activity android:name=".MySearchableActivity" android:launchMode="singleTop" > <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/> </activity>
如何給搜尋方塊增加參數
要給搜尋方塊傳遞參數,我們需要重寫onSearchRequested()方法,如下所示:
@Override<br />public boolean onSearchRequested() {<br /> Bundle appData = new Bundle();<br /> appData.putBoolean(MySearchableActivity.JARGON, true);<br /> startSearch(null, false, appData, false);<br /> return true;<br /> }
我們的Activity在收到搜尋方塊的搜尋請求時,通過如下方法擷取參數:
Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);<br /> if (appData != null) {<br /> boolean jargon = appData.getBoolean(MySearchableActivity.JARGON);<br /> }
最後我們來看看如何使用android的語音搜尋
:
只需要對我們的搜尋設定檔做如下改動,你的搜尋就支援語音搜尋了,設定檔如下所示:
<?xml version="1.0" encoding="utf-8"?><br /><searchable xmlns:android="http://schemas.android.com/apk/res/android"<br /> android:label="@string/searchLabel"<br /> android:hint="@string/searchHint"<br /> android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"><br /></searchable>
好了,今天就到這兒,自己動手練習去吧!以後還會詳細講解如何增加搜尋建議,語音搜尋等內容。
樣本程式下載:http://www.ideasandroid.com/android/demo/FloatSearchBoxDemo.rar