編寫(xiě):Lin-H - 原文:http://developer.android.com/training/search/setup.html
從Android 3.0開(kāi)始,在action bar中使用SearchView作為item,是在你的app中提供搜索的一種更好方法。像其他所有在action bar中的item一樣,你可以定義SearchView在有足夠空間的時(shí)候總是顯示,或設(shè)置為一個(gè)折疊操作(collapsible action),一開(kāi)始SearchView作為一個(gè)圖標(biāo)顯示,當(dāng)用戶點(diǎn)擊圖標(biāo)時(shí)再顯示搜索框占據(jù)整個(gè)action bar。
Note:在本課程的后面,你會(huì)學(xué)習(xí)對(duì)那些不支持SearchView的設(shè)備,如何使你的app向下兼容至Android 2.1(API level 7)版本。
為了在action bar中添加SearchView,在你的工程目錄res/menu/
中創(chuàng)建一個(gè)名為options_menu.xml
的文件,再把下列代碼添加到文件中。這段代碼定義了如何創(chuàng)建search item,比如使用的圖標(biāo)和item的標(biāo)題。collapseActionView
屬性允許你的SearchView占據(jù)整個(gè)action bar,在不使用的時(shí)候折疊成普通的action bar item。由于在手持設(shè)備中action bar的空間有限,建議使用collapsibleActionView
屬性來(lái)提供更好的用戶體驗(yàn)。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/search"
android:title="@string/search_title"
android:icon="@drawable/ic_search"
android:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="android.widget.SearchView" />
</menu>
Note:如果你的menu items已經(jīng)有一個(gè)XML文件,你可以只把
<item>
元素添加入文件。
要在action bar中顯示SearchView,在你的activity中onCreateOptionsMenu()方法內(nèi)填充XML菜單資源(res/menu/options_menu.xml
):
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
如果你立即運(yùn)行你的app,SearchView就會(huì)顯示在你app的action bar中,但還無(wú)法使用。你現(xiàn)在需要定義SearchView如何運(yùn)行。
檢索配置(searchable configuration)在 res/xml/searchable.xml
文件中定義了SearchView如何運(yùn)行。檢索配置中至少要包含一個(gè)android:label
屬性,與Android manifest中的<application>
或<activity>
android:label
屬性值相同。但我們還是建議添加android:hint
屬性來(lái)告訴用戶應(yīng)該在搜索框中輸入什么內(nèi)容:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint" />
在你的應(yīng)用的manifest文件中,聲明一個(gè)指向res/xml/searchable.xml
文件的<meta-data>
元素,來(lái)告訴你的應(yīng)用在哪里能找到檢索配置。在你想要顯示SearchView的<activity>
中聲明<meta-data>
元素:
<activity ... >
...
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
在你之前創(chuàng)建的onCreateOptionsMenu()方法中,調(diào)用setSearchableInfo(SearchableInfo)把SearchView和檢索配置關(guān)聯(lián)在一起:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
// 關(guān)聯(lián)檢索配置和SearchView
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
return true;
}
調(diào)用getSearchableInfo()返回一個(gè)SearchableInfo由檢索配置XML文件創(chuàng)建的對(duì)象。檢索配置與SearchView正確關(guān)聯(lián)后,當(dāng)用戶提交一個(gè)搜索請(qǐng)求時(shí),SearchView會(huì)以ACTION_SEARCH intent啟動(dòng)一個(gè)activity。所以你現(xiàn)在需要一個(gè)能過(guò)濾這個(gè)intent和處理搜索請(qǐng)求的activity。
當(dāng)用戶提交一個(gè)搜索請(qǐng)求時(shí),SearchView會(huì)嘗試以ACTION_SEARCH啟動(dòng)一個(gè)activity。檢索activity會(huì)過(guò)濾ACTION_SEARCH intent并在某種數(shù)據(jù)集中根據(jù)請(qǐng)求進(jìn)行搜索。要?jiǎng)?chuàng)建一個(gè)檢索activity,在你選擇的activity中聲明對(duì)ACTION_SEARCH intent過(guò)濾:
<activity android:name=".SearchResultsActivity" ... >
...
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
...
</activity>
在你的檢索activity中,通過(guò)在onCreate()方法中檢查ACTION_SEARCH intent來(lái)處理它。
Note:如果你的檢索activity在single top mode下啟動(dòng)(
android:launchMode="singleTop"
),也要在onNewIntent()方法中處理ACTION_SEARCH intent。在single top mode下你的activity只有一個(gè)會(huì)被創(chuàng)建,而隨后啟動(dòng)的activity將不會(huì)在棧中創(chuàng)建新的activity。這種啟動(dòng)模式很有用,因?yàn)橛脩艨梢栽诋?dāng)前activity中進(jìn)行搜索,而不用在每次搜索時(shí)都創(chuàng)建一個(gè)activity實(shí)例。
public class SearchResultsActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
...
handleIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
...
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
//通過(guò)某種方法,根據(jù)請(qǐng)求檢索你的數(shù)據(jù)
}
}
...
}
如果你現(xiàn)在運(yùn)行你的app,SearchView就能接收用戶的搜索請(qǐng)求,以ACTION_SEARCH intent啟動(dòng)你的檢索activity?,F(xiàn)在就由你來(lái)解決如何依據(jù)請(qǐng)求來(lái)儲(chǔ)存和搜索數(shù)據(jù)。