本篇講的是如何用searchView實現搜索框,其實原理和以前的沒啥差異,也算是個複習吧。html
1、Manifest.xmlandroid
這裏我用一個activity進行信息的輸入和展現,配置方式仍是老樣子,寫一個輸入框的配置文件,而後寫定一個actionexpress
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.kale.searchview" android:versionCode="1" android:versionName="1.0" ><uses-permission android:name="android.permission.READ_CONTACTS"/><uses-sdk android:minSdkVersion="11" 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" android:windowSoftInputMode = "adjustPan"><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>
2、searchable.xmlapache
<?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" android:icon="@drawable/ic_launcher" android:searchMode="queryRewriteFromText" />
3、MainActivityapp
3.1 設置SearchViewless
貼代碼以前先說下searchview的設置,searchview有不少設置方案,詳細能夠參考官方的文檔,下面是我舉得幾個例子:ide
mSearchView = (SearchView) findViewById(R.id.search); /** * 默認狀況下, search widget是"iconified「的,只是用一個圖標 來表示它(一個放大鏡), * 當用戶按下它的時候才顯示search box . 你能夠調用setIconifiedByDefault(false)讓search * box默認都被顯示。 你也能夠調用setIconified()讓它以iconified「的形式顯示。 */ mSearchView.setIconifiedByDefault(true); /** * 默認狀況下是沒提交搜索的按鈕,因此用戶必須在鍵盤上按下"enter"鍵來提交搜索.你能夠同過setSubmitButtonEnabled( * true)來添加一個提交按鈕("submit" button) * 設置true後,右邊會出現一個箭頭按鈕。若是用戶沒有輸入,就不會觸發提交(submit)事件 */ mSearchView.setSubmitButtonEnabled(true); /** * 初始是否已是展開的狀態 * 寫上此句後searchView初始展開的,也就是是能夠點擊輸入的狀態,若是不寫,那麼就須要點擊下放大鏡,才能展開出現輸入框 */ mSearchView.onActionViewExpanded(); // 設置search view的背景色 mSearchView.setBackgroundColor(0x22ff00ff); /** * 默認狀況下, search widget是"iconified「的,只是用一個圖標 來表示它(一個放大鏡), * 當用戶按下它的時候才顯示search box . 你能夠調用setIconifiedByDefault(false)讓search * box默認都被顯示。 你也能夠調用setIconified()讓它以iconified「的形式顯示。 */ mSearchView.setIconifiedByDefault(true);
3.2 配置監聽器ui
這段代碼以前見過,監聽器中的方法會在用戶輸入和提交搜索結果時觸發this
mSearchView.setOnQueryTextListener(new OnQueryTextListener() { private String TAG = getClass().getSimpleName(); /* * 在輸入時觸發的方法,當字符真正顯示到searchView中才觸發,像是拼音,在舒服法組詞的時候不會觸發 * * @param queryText * * @return false if the SearchView should perform the default action * of showing any suggestions if available, true if the action was * handled by the listener. */ @Override public boolean onQueryTextChange(String queryText) { Log.d(TAG, "onQueryTextChange = " + queryText); String selection = RawContacts.DISPLAY_NAME_PRIMARY + " LIKE '%" + queryText + "%' " + " OR " + RawContacts.SORT_KEY_PRIMARY + " LIKE '%" + queryText + "%' "; // String[] selectionArg = { queryText }; mCursor = getContentResolver().query(RawContacts.CONTENT_URI, PROJECTION, selection, null, null); mAdapter.swapCursor(mCursor); // 交換指針,展現新的數據return true; } /* * 輸入完成後,提交時觸發的方法,通常狀況是點擊輸入法中的搜索按鈕纔會觸發。表示如今正式提交了 * * @param queryText * * @return true to indicate that it has handled the submit request. * Otherwise return false to let the SearchView handle the * submission by launching any associated intent. */ @Override public boolean onQueryTextSubmit(String queryText) { Log.d(TAG, "onQueryTextSubmit = " + queryText); if (mSearchView != null) { // 獲得輸入管理對象 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) { // 這將讓鍵盤在全部的狀況下都被隱藏,可是通常咱們在點擊搜索按鈕後,輸入法都會乖乖的自動隱藏的。 imm.hideSoftInputFromWindow(mSearchView.getWindowToken(), 0); // 輸入法若是是顯示狀態,那麼就隱藏輸入法 } mSearchView.clearFocus(); // 不獲取焦點 } return true; } });
3.3 所有代碼spa
package com.kale.searchview; import android.app.SearchManager; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.provider.ContactsContract; import android.provider.ContactsContract.RawContacts; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.inputmethod.InputMethodManager; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListView; import android.widget.SearchView; import android.widget.SearchView.OnQueryTextListener; import android.widget.SimpleCursorAdapter; public class MainActivity extends ActionBarActivity { private SearchView mSearchView; private ListView mListView; private SimpleCursorAdapter mAdapter; private Cursor mCursor; static final String[] PROJECTION = new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 獲得聯繫人名單的指針 mCursor = getContentResolver().query(RawContacts.CONTENT_URI, PROJECTION, null, null, null); // 經過傳入mCursor,將聯繫人名字放入listView中。 mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, mCursor, new String[] { RawContacts.DISPLAY_NAME_PRIMARY }, new int[] { android.R.id.text1 }, 0); mListView = (ListView) findViewById(android.R.id.list); mListView.setAdapter(mAdapter); mListView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) { imm.hideSoftInputFromWindow(mListView.getWindowToken(), 0); // 輸入法若是是顯示狀態,那麼就隱藏輸入法 } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); mSearchView = (SearchView) findViewById(R.id.search); /** * 默認狀況下, search widget是"iconified「的,只是用一個圖標 來表示它(一個放大鏡), * 當用戶按下它的時候才顯示search box . 你能夠調用setIconifiedByDefault(false)讓search * box默認都被顯示。 你也能夠調用setIconified()讓它以iconified「的形式顯示。 */ mSearchView.setIconifiedByDefault(true); /** * 默認狀況下是沒提交搜索的按鈕,因此用戶必須在鍵盤上按下"enter"鍵來提交搜索.你能夠同過setSubmitButtonEnabled( * true)來添加一個提交按鈕("submit" button) * 設置true後,右邊會出現一個箭頭按鈕。若是用戶沒有輸入,就不會觸發提交(submit)事件 */ mSearchView.setSubmitButtonEnabled(true); /** * 初始是否已是展開的狀態 * 寫上此句後searchView初始展開的,也就是是能夠點擊輸入的狀態,若是不寫,那麼就須要點擊下放大鏡,才能展開出現輸入框 */ mSearchView.onActionViewExpanded(); // 設置search view的背景色 mSearchView.setBackgroundColor(0x22ff00ff); /** * 默認狀況下, search widget是"iconified「的,只是用一個圖標 來表示它(一個放大鏡), * 當用戶按下它的時候才顯示search box . 你能夠調用setIconifiedByDefault(false)讓search * box默認都被顯示。 你也能夠調用setIconified()讓它以iconified「的形式顯示。 */ mSearchView.setIconifiedByDefault(true); mSearchView.setOnQueryTextListener(new OnQueryTextListener() { private String TAG = getClass().getSimpleName(); /* * 在輸入時觸發的方法,當字符真正顯示到searchView中才觸發,像是拼音,在舒服法組詞的時候不會觸發 * * @param queryText * * @return false if the SearchView should perform the default action * of showing any suggestions if available, true if the action was * handled by the listener. */ @Override public boolean onQueryTextChange(String queryText) { Log.d(TAG, "onQueryTextChange = " + queryText); String selection = RawContacts.DISPLAY_NAME_PRIMARY + " LIKE '%" + queryText + "%' " + " OR " + RawContacts.SORT_KEY_PRIMARY + " LIKE '%" + queryText + "%' "; // String[] selectionArg = { queryText }; mCursor = getContentResolver().query(RawContacts.CONTENT_URI, PROJECTION, selection, null, null); mAdapter.swapCursor(mCursor); // 交換指針,展現新的數據return true; } /* * 輸入完成後,提交時觸發的方法,通常狀況是點擊輸入法中的搜索按鈕纔會觸發。表示如今正式提交了 * * @param queryText * * @return true to indicate that it has handled the submit request. * Otherwise return false to let the SearchView handle the * submission by launching any associated intent. */ @Override public boolean onQueryTextSubmit(String queryText) { Log.d(TAG, "onQueryTextSubmit = " + queryText); if (mSearchView != null) { // 獲得輸入管理對象 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) { // 這將讓鍵盤在全部的狀況下都被隱藏,可是通常咱們在點擊搜索按鈕後,輸入法都會乖乖的自動隱藏的。 imm.hideSoftInputFromWindow(mSearchView.getWindowToken(), 0); // 輸入法若是是顯示狀態,那麼就隱藏輸入法 } mSearchView.clearFocus(); // 不獲取焦點 } return true; } }); } }
4、ActionBar上的搜索框
若是咱們想要實現下面這種效果,將搜索框放在actionbar上,該怎麼作呢?
實現方式在menu菜單中添加一個searchview,而後在初始化菜單的時候進行配置
4.1 options_menu.xml
<!-- /* ** Copyright 2010, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ --><!-- Options Menu for SearchableActivity and WordActivity. --><menu xmlns:android="http://schemas.android.com/apk/res/android"><item android:id="@+id/search" android:title="@string/search" android:icon="@drawable/ic_menu_search" android:showAsAction="collapseActionView|ifRoom" android:actionViewClass="android.widget.SearchView" /></menu>
Java
這裏我沒綁定監聽器,其實徹底能夠在這裏給searchview綁定監聽器的。
/* * search widget如今已經被配置好了,系統也可以把搜索命令發送到你的Searchable activity. * 你也能夠在 search widget中使用search suggestions。 * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.options_menu, menu); SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView(); SearchableInfo info = searchManager.getSearchableInfo(getComponentName()); searchView.setSearchableInfo(info); searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by defaultreturn true; }
這樣寫完後,search後的結果就會傳送到你想要處理搜索結果的activity中了(本例是當前的activity)
@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(); }
所有代碼:
package com.kale.searchview; import android.app.Activity; import android.app.SearchManager; import android.app.SearchableInfo; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.provider.ContactsContract; import android.provider.ContactsContract.RawContacts; import android.util.Log; import android.view.Menu; import android.view.inputmethod.InputMethodManager; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListView; import android.widget.SearchView; import android.widget.Toast; import android.widget.SearchView.OnQueryTextListener; import android.widget.SimpleCursorAdapter; public class MainActivity extends Activity { private SearchView mSearchView; private ListView mListView; private SimpleCursorAdapter mAdapter; private Cursor mCursor; static final String[] PROJECTION = new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 獲得聯繫人名單的指針 mCursor = getContentResolver().query(RawContacts.CONTENT_URI, PROJECTION, null, null, null); // 經過傳入mCursor,將聯繫人名字放入listView中。 mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, mCursor, new String[] { RawContacts.DISPLAY_NAME_PRIMARY }, new int[] { android.R.id.text1 }, 0); mListView = (ListView) findViewById(android.R.id.list); mListView.setAdapter(mAdapter); mListView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) { imm.hideSoftInputFromWindow(mListView.getWindowToken(), 0); // 輸入法若是是顯示狀態,那麼就隱藏輸入法 } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); mSearchView = (SearchView) findViewById(R.id.search); /** * 默認狀況下, search widget是"iconified「的,只是用一個圖標 來表示它(一個放大鏡), * 當用戶按下它的時候才顯示search box . 你能夠調用setIconifiedByDefault(false)讓search * box默認都被顯示。 你也能夠調用setIconified()讓它以iconified「的形式顯示。 */ mSearchView.setIconifiedByDefault(true); /** * 默認狀況下是沒提交搜索的按鈕,因此用戶必須在鍵盤上按下"enter"鍵來提交搜索.你能夠同過setSubmitButtonEnabled( * true)來添加一個提交按鈕("submit" button) * 設置true後,右邊會出現一個箭頭按鈕。若是用戶沒有輸入,就不會觸發提交(submit)事件 */ mSearchView.setSubmitButtonEnabled(true); /** * 初始是否已是展開的狀態 * 寫上此句後searchView初始展開的,也就是是能夠點擊輸入的狀態,若是不寫,那麼就須要點擊下放大鏡,才能展開出現輸入框 */ mSearchView.onActionViewExpanded(); // 設置search view的背景色 mSearchView.setBackgroundColor(0xff000000); /** * 默認狀況下, search widget是"iconified「的,只是用一個圖標 來表示它(一個放大鏡), * 當用戶按下它的時候才顯示search box . 你能夠調用setIconifiedByDefault(false)讓search * box默認都被顯示。 你也能夠調用setIconified()讓它以iconified「的形式顯示。 */ mSearchView.setIconifiedByDefault(true); mSearchView.setOnQueryTextListener(new OnQueryTextListener() { private String TAG = getClass().getSimpleName(); /* * 在輸入時觸發的方法,當字符真正顯示到searchView中才觸發,像是拼音,在舒服法組詞的時候不會觸發 * * @param queryText * * @return false if the SearchView should perform the default action * of showing any suggestions if available, true if the action was * handled by the listener. */ @Override public boolean onQueryTextChange(String queryText) { Log.d(TAG, "onQueryTextChange = " + queryText); String selection = RawContacts.DISPLAY_NAME_PRIMARY + " LIKE '%" + queryText + "%' " + " OR " + RawContacts.SORT_KEY_PRIMARY + " LIKE '%" + queryText + "%' "; // String[] selectionArg = { queryText }; mCursor = getContentResolver().query(RawContacts.CONTENT_URI, PROJECTION, selection, null, null); mAdapter.swapCursor(mCursor); // 交換指針,展現新的數據return true; } /* * 輸入完成後,提交時觸發的方法,通常狀況是點擊輸入法中的搜索按鈕纔會觸發。表示如今正式提交了 * * @param queryText * * @return true to indicate that it has handled the submit request. * Otherwise return false to let the SearchView handle the * submission by launching any associated intent. */ @Override public boolean onQueryTextSubmit(String queryText) { Log.d(TAG, "onQueryTextSubmit = " + queryText); if (mSearchView != null) { // 獲得輸入管理對象 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) { // 這將讓鍵盤在全部的狀況下都被隱藏,可是通常咱們在點擊搜索按鈕後,輸入法都會乖乖的自動隱藏的。 imm.hideSoftInputFromWindow(mSearchView.getWindowToken(), 0); // 輸入法若是是顯示狀態,那麼就隱藏輸入法 } mSearchView.clearFocus(); // 不獲取焦點 } return true; } }); } @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(); } /* * search widget如今已經被配置好了,系統也可以把搜索命令發送到你的Searchable activity. * 你也能夠在 search widget中使用search suggestions。 * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.options_menu, menu); SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView(); SearchableInfo info = searchManager.getSearchableInfo(getComponentName()); searchView.setSearchableInfo(info); searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by defaultreturn true; } }
源碼下載:http://download.csdn.net/detail/shark0017/8364947
關於全局搜索請參考:http://blog.csdn.net/imdxt1986/article/details/7311958
再貼一個以前收集的demo,感受是比較完善,但不效果不是很好。須要的話能夠參考:http://download.csdn.net/detail/shark0017/8365121
參考自:
http://blog.csdn.net/hudashi/article/details/7052846