Android4.0之後,Android內置了一個搜索控件,配合ActionBar上面的搜索按鈕,相當不錯好看,這次使用了下,覺得很不錯。
這個搜索的好處在於你點擊後,他會自動彈出個搜索框,輸入內容後會自動彈出匹配的內容,形成一個列表,選擇後會彈到你想要去的界面。
類似這樣的
你需要在代碼中的onCreateOptionsMenu中加入
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
然後在onOptionsItemSelected中加入
case R.id.search:
onSearchRequested();
return true;
這樣才會執行搜索功能。
從開始看代碼
handleIntent(getIntent());這個方法在onCreate中就執行了
並且在
@Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
}
也執行了,說明這個方法比算較重要,其實這個是一個搜索按鈕用的因為在android4.0以上系統 輸入法裡有個“搜索”按鈕或者是“前往”按鈕
這樣的搜索按鈕,這個 handleIntent(getIntent())主要就是執行的這個搜索
看裡面的代碼:
private void handleIntent(Intent intent) {
//Intent.ACTION_VIEW android:searchSuggestIntentAction="android.intent.action.VIEW" 還在這個view中
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
// handles a click on a search suggestion; launches activity to show word
Intent wordIntent = new Intent(this, WordActivity.class);
wordIntent.setData(intent.getData());
startActivity(wordIntent);
finish();
} else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
// handles a search query Intent.ACTION_SEARCH這個Intent是在當我點擊系統的搜索框右面的按鈕時觸發的
String query = intent.getStringExtra(SearchManager.QUERY);
showResults(query);
}
}
上面就是handleIntent裡面的代碼
handleIntent裡的代碼有兩個意思 一個就是當Intent是Intent.ACTION_VIEW.這個的時候跳到你指定的類中必然WordActivity,其實這個ntent.ACTION_VIEW就是你在搜索出建議後點擊建議裡面的列表進入的界面,比如你點擊這個就執行的是這個intent,執行這個intent,會返回一個URI,可以使用intent.getData()這個方法得到這個返回的URI,這個URI是系統自己返回的。可以看配置文件searchable.xml這個文件,這個文件的代碼如下:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/search_label"
android:hint="@string/search_hint"
android:searchSettingsDescription="@string/settings_description"
android:searchSuggestAuthority="com.example.android.searchabledict.DictionaryProvider"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestIntentData="content://com.example.android.searchabledict.DictionaryProvider/dictionary/sugger_que54r"
android:searchSuggestSelection=" ?"
android:searchSuggestThreshold="1"
android:includeInGlobalSearch="true"
>
</searchable>
就是一個XML文件,裡面配置的是android:searchSuggestAuthority這個是在AndroidManifest.xml裡面配置的provider,比如
<provider android:name=".DictionaryProvider"
android:authorities="com.example.android.searchabledict.DictionaryProvider" />
裡面的android:searchSuggestIntentData配置的就是你要返回的intentData,比如這裡面配的是content://com.example.android.searchabledict.DictionaryProvider/dictionary/sugger_que54r到時候你在
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
// handles a click on a search suggestion; launches activity to show word
Intent wordIntent = new Intent(this, WordActivity.class);
wordIntent.setData(intent.getData());
startActivity(wordIntent);
finish();
} 這個裡面的intent.getData()就會是content://com.example.android.searchabledict.DictionaryProvider/dictionary/sugger_que54r/(你點擊的那個Item的ID)也就是一個帶ID的URI,至於這裡的ID,是你在代碼裡賦值給他的 ,這個後面說。
當如果是你點擊右下角的搜索按鈕的時候執行的是ACTION_SEARCH這個intent,會執行showResults這個方法。
private void showResults(String query) {
Cursor cursor = managedQuery(DictionaryProvider.CONTENT_URI, null, selection,
new String[]{query}, null);
if (cursor == null) {
// There are no results
mTextView.setText(getString(R.string.no_results, new Object[] {query}));
} else {
// Display the number of results
int count = cursor.getCount();
String countString = getResources().getQuantityString(R.plurals.search_results,
count, new Object[] {count, query});
mTextView.setText(countString);
// Specify the columns we want to display in the result
String[] from = new String[] { DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION };
// Specify the corresponding layout elements where we want the columns to go
int[] to = new int[] { R.id.word,
R.id.definition };
// Create a simple cursor adapter for the definitions and apply them to the ListView
SimpleCursorAdapter words = new SimpleCursorAdapter(this,
R.layout.result, cursor, from, to);
mListView.setAdapter(words);
// Define the on-click listener for the list items
mListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Build the Intent used to open WordActivity with a specific word Uri
Intent wordIntent = new Intent(getApplicationContext(), WordActivity.class);
Uri data = Uri.withAppendedPath(DictionaryProvider.CONTENT_URI,
String.valueOf(id));
wordIntent.setData(data);
startActivity(wordIntent);
}
});
}
}
以上是showResult這個方法裡穿進去的query這個字符串就是你搜索時候輸入的字符串。managedQuery就是你自己想怎麼搜索自己定義的搜索語句,然後搜索出結果。
接下來解釋下 String countString = getResources().getQuantityString(R.plurals.search_results,
count, new Object[] {count, query});
這段代碼。這段代碼只要是plurals,plurals是一個復數,是在String.xml文件中配置的,配置文件如下:
<plurals name="search_results">
<item quantity="one">%1$d result for \"%2$s\": </item>
<item quantity="other">%1$d results for \"%2$s\": </item>
</plurals>
plurals的負數的意思是,如果要是查出的結果是一個也就是quantity="one",則提示%1$d result for \"%2$s\"這裡的%1$d和 \"%2$s\"都是類似占位符,取的是前面new Object[] {count, query}傳進來的值,這裡主要是區分一個和多個,不如一個時候提示你搜索的結果是1個,多個的時候提示你搜索的結果有多個,可能英語中result和results這種復數的不同導致他們這樣設計,你也可以設置 <item quantity="two">這種根據自己的定義提示。
接下來就進入一個列表,然後點擊列表中的數據,會執行你自己定義的方法,需要提示的是item的ID是你傳值進去的
我們來看provider中,provider中buildUriMatcher這個方法主要是根據你的URI匹配來進行的,比如 matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);就會返回一個SEARCH_SUGGEST這樣的int值,
這個方法主要是在query這個方法中做判斷:
如下:
switch (sURIMatcher.match(uri)) {
case SEARCH_SUGGEST:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return getSuggestions(selectionArgs[0]);
case SEARCH_WORDS:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return search(selectionArgs[0]);
這樣就會執行你的方法,這些方法,都是你輸入關鍵字時候系統自動搜索的,你需要把你的自動賦值給系統定義好的字段,查詢語句類似如下:
String[] columns = new String[] {
BaseColumns._ID,
BaseColumns._ID+" AS "+SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID,
CorpInfoColumns.NAME+" AS "+SearchManager.SUGGEST_COLUMN_TEXT_1,
CorpInfoColumns.LEGAL_PERSON+" AS "+SearchManager.SUGGEST_COLUMN_TEXT_2
};
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
String selection = CorpInfoColumns.NAME + " like ? OR "+CorpInfoColumns.LEGAL_PERSON+ " like ? ";
String[] selectionArgs = new String[] {"%"+query+"%","%"+query+"%"};、
你需要把你自己的_id的行名必須為給SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID,這樣前面才會返回一個帶ID的URI,把你搜索的第一行命名給SearchManager.SUGGEST_COLUMN_TEXT_1,第二行的行名必須為SearchManager.SUGGEST_COLUMN_TEXT_2,這樣系統才會自動顯示。否則會顯示一片白色。
這個adapter其實應該可以自己定義的,只不過我沒有定義過,有興趣的可以試試