Search Dialog是提供搜索的控件之一,還有一個是上次小例子給出的searchView,關於SearchView的東西后面會說到。本次先從Search Dialog提及,讓你們慢慢理解android中搜索的控件的機制,逐漸引出搜索信息傳遞和搜索配置的知識,鋪墊到最後再給你們說searchview的話,你們就能很容易理解。 html
1、Search Dialog 和 Search Viewjava
這兩個其實都是一個搜索控件,區別不大,但多少仍是有些小的差別的。android
不一樣點:程序員
該文件通常約定爲searchable.xml並位於res/xml/目錄下。searchable.xml必須以<searchable> element 做爲根節點,且至少定義一個屬性。
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:hint="@string/search_hint" android:label="@string/app_name" android:icon="@drawable/kale"> </searchable>
<activity android:name=".MainActivity" android:label="@string/app_name" android:launchMode="singleTop" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <!-- enable the search dialog to send searches to SearchableActivity --> <meta-data android:name="android.app.default_searchable" android:value="com.kale.searchdialogtest.SearchActivity" /> </activity> <activity android:name="com.kale.searchdialogtest.SearchActivity" 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>
爲了方便解釋,咱們直接看主要代碼:app
MainActivity:ide
<activity android:name=".MainActivity" android:launchMode="singleTop" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <!-- enable the search dialog to send searches to SearchableActivity --> <meta-data android:name="android.app.default_searchable" android:value="com.kale.searchdialogtest.SearchActivity" /> </activity>
<!-- enable the search dialog to send searches to SearchableActivity --> <meta-data android:name="android.app.default_searchable" android:value="com.kale.searchdialogtest.SearchActivity" />
1. 必須包含「
android:value」屬性,該屬性指明瞭
searchable activity的類名,
android:name",
且其值必須爲 "android.app.default_searchable"
.
<activity android:name="com.kale.searchdialogtest.SearchActivity" 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>
依據建議,用於展現搜索結果的activity應該用singleTop模式,同時要強制寫上以下內容。佈局
<intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" />
若是對activity的隱式啓動有所瞭解的話,咱們一眼就看出爲何要這麼定義了。在MainActivity中系統會在用戶提交搜索時產生一個intent,而且給intent放入搜索詞,並且還定義了一個action。系統這時就開始找哪一個activity中定義了 <action android:name="android.intent.action.SEARCH" />,找到這個activity後就會自動啓動咱們的這個searchActivity。至於meta-data中的東西,其實就是一個search的配置信息。ui
package com.kale.searchdialogtest;public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.show_dialog_button); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onSearchRequested(); } }); } }
很簡單吧,經過onSearchRequested()咱們就可讓activity中顯示出一個search dialog,因此在某種意義上說,search dialog不用程序員進行過多幹預。this
package com.kale.searchdialogtest; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.show_dialog_button); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onSearchRequested(); } }); } // 重寫onSearchRequested方法 @Override public boolean onSearchRequested() { // 除了輸入查詢的值,還可額外綁定一些數據 Bundle appSearchData = new Bundle(); appSearchData.putString("KEY", "text"); startSearch(null, false, appSearchData, false); // 必須返回true。不然綁定的數據做廢 return true; } }
咱們在這裏面放入了一個鍵值對,KEY-text。spa
package com.kale.searchdialogtest; import android.app.Activity; import android.app.SearchManager; import android.content.Intent; import android.os.Bundle; import android.widget.TextView; import android.widget.Toast; /** * @author:Jack Tony * @description :真正執行搜索和結果展現的Activity 一旦用戶在search dialog中執行search操做, * 系統將啓動SearchableActivity 並向其傳送ACTION_SEARCH intent. * @date :2015年1月15日 * * 參考自:http://zhouyunan2010.iteye.com/blog/1134147 */ public class SearchActivity extends Activity { protected void onCreate(android.os.Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search_activity); // Get the intent, verify the action and get the query Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); doMySearch(query); } // 得到額外遞送過來的值 Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA); if (appData != null) { String testValue = appData.getString("KEY"); System.out.println("extra data = " + testValue); } } private void doMySearch(String query) { // TODO 自動生成的方法存根 TextView textView = (TextView) findViewById(R.id.search_result_textView); textView.setText(query); Toast.makeText(this, "do search", 0).show(); } }
主要內容是從intent中得到數據,而後進行處理。這裏僅僅得到了數據,沒有進行真正的搜索。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.kale.searchdialogtest" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" 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> </application> </manifest>
<activity android:name=".MainActivity" >
<intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity>
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable" />
<meta-data android:name="android.app.default_searchable" android:value="com.kale.searchdialogtest.MainActivity" />
package com.kale.searchdialogtest; import android.app.SearchManager; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); handleIntent(getIntent()); Button btn = (Button) findViewById(R.id.show_dialog_button); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onSearchRequested(); } }); } private void handleIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); doMySearch(query); } } private void doMySearch(String query) { // TODO 自動生成的方法存根 Toast.makeText(this, "do search " + query, 0).show(); } }
<activity android:name=".MainActivity" android:label="@string/app_name" android:launchMode="singleTop" > <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>
package com.kale.searchdialogtest; import android.app.SearchManager; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; /** * @author:Jack Tony * @description : * * 當系統調用onNewIntent(Intent)的時候,表示activity並非新建的, 因此getIntent()返回的仍是 * 在onCreate()中接受到的intent. * 所以你必須在onNewIntent(Intent)調用setIntent(Intent)來 * (這樣保存的intent才被更新,以後你能夠同過getIntent()來取得它). * * @date :2015年1月15日 */ public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.show_dialog_button); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onSearchRequested(); } }); } @Override protected 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); } } private void doMySearch(String query) { // TODO 自動生成的方法存根 Toast.makeText(this, "do search " + query, 0).show(); } }
onNewIntent(Intent)的時候,表示
activity並非新建的, 因此getIntent()返回的仍是
在onCreate()中接受到的intent
. 所以你必須在onNewIntent(Intent)調用
setIntent(Intent)來 (這樣保存的intent才被更新,以後你能夠同過getIntent()來取得它
)