歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android SearchView 搜索框

如果對這個效果感覺不錯, 請往下看.

背景: 天氣預報app, 本地數據庫存儲70個大中城市的基本信息, 根據用戶輸入的或通過搜索框選取的城市, 點擊查詢按鈕後, 異步請求國家氣象局數據, 得到返回的json解析並顯示.

1. 先說AndroidManifest.xml文件

  1. <uses-sdk
  2. android:minSdkVersion="11"
  3. android:targetSdkVersion="16"/>
  4. <application>
  5. <activity
  6. android:name="com.lichen.weather.WeatherActivity"
  7. android:launchMode="singleTop"
  8. android:label="@string/app_name">
  9. <intent-filter>
  10. <!-- 省略 -->
  11. </intent-filter>
  12. <!-- 關注1 -->
  13. <!-- Receives the search request. -->
  14. <intent-filter>
  15. <actionandroid:name="android.intent.action.SEARCH"/>
  16. <!-- No category needed, because the Intent will specify this class component-->
  17. </intent-filter>
  18. <!-- Points to searchable meta data. -->
  19. <meta-dataandroid:name="android.app.searchable"
  20. android:resource="@xml/searchable"/>
  21. <!-- /關注1 -->
  22. </activity>
  23. <providerandroid:name="com.lichen.db.CityContentProvider"
  24. android:authorities="com.lichen.cityprovider"
  25. android:label="@string/app_name"></provider>
  26. <!-- 關注2 -->
  27. <!-- Points to searchable activity so the whole app can invoke search. -->
  28. <meta-dataandroid:name="android.app.default_searchable"
  29. android:value="com.lichen.weather.WeatherActivity"/>
  30. <!-- /關注2 -->
  31. </application>

2. menu菜單裡面加入

  1. <menuxmlns:android="http://schemas.android.com/apk/res/android">
  2. <itemandroid:id="@+id/search"
  3. android:title="@string/menu_search"
  4. android:showAsAction="collapseActionView|ifRoom"
  5. android:actionViewClass="android.widget.SearchView"/>
  6. </menu>

3. 然後在res目錄下新建xml/searchable.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <searchable xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:label="@string/search_label"
  4. android:hint="@string/search_hint"
  5. android:searchSuggestAuthority="com.lichen.cityprovider"
  6. android:searchSuggestIntentAction="android.intent.action.VIEW"
  7. android:searchSuggestIntentData="content://com.lichen.cityprovider/city"
  8. android:searchSuggestSelection=" ?"
  9. android:searchSuggestThreshold="1"
  10. android:includeInGlobalSearch="true">
  11. </searchable>

字符串盡量使用@string/search_label這種方式.

4. Activity中

因為注冊Activity的啟動方式為android:launchMode="singleTop",需要Activity的protectedvoid onNewIntent(Intent intent) {}來交互.

  1. @Override
  2. protectedvoid onNewIntent(Intent intent) {
  3. handleIntent(intent);
  4. }
  5. privatevoid handleIntent(Intent intent) {
  6. if (Intent.ACTION_VIEW.equals(intent.getAction())) {
  7. //查詢數據庫
  8. Cursor searchCursor = getContentResolver().query(intent.getData(), null, null, null, null);
  9. if (searchCursor != null && searchCursor.moveToFirst()) {
  10. cityInput.setText(searchCursor.getString(searchCursor.getColumnIndex(City.CITY_DESCRIBE)));
  11. }
  12. }
  13. @Override
  14. publicboolean onCreateOptionsMenu(Menu menu) {
  15. getMenuInflater().inflate(R.menu.activity_weather, menu);
  16. SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
  17. SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
  18. searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
  19. searchView.setIconifiedByDefault(false);
  20. returntrue;
  21. }

以上的在網上可以搜索到,接下來是重點...

5. 需要數據庫支持

  1. publicclass CityDatabaseHelper extends SQLiteOpenHelper {
  2. protectedstaticfinal String DATABASE_NAME = "city.db";
  3. protectedstaticfinalint DATABASE_VERSION = 6;
  4. public String[] columns = new String[] {
  5. SearchManager.SUGGEST_COLUMN_TEXT_1,
  6. SearchManager.SUGGEST_COLUMN_TEXT_2,
  7. SearchManager.SUGGEST_COLUMN_ICON_1,
  8. SearchManager.SUGGEST_COLUMN_ICON_2,
  9. BaseColumns._ID,
  10. SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
  11. privatestaticfinal HashMap<String,String> mColumnMap = buildColumnMap();
  12. public CityDatabaseHelper(Context context) {
  13. super(context, DATABASE_NAME, null, DATABASE_VERSION);
  14. }
  15. privatestatic HashMap<String,String> buildColumnMap() {
  16. HashMap<String,String> map = new HashMap<String,String>();
  17. map.put(SearchManager.SUGGEST_COLUMN_TEXT_1, City.CITY_DESCRIBE + " as "+SearchManager.SUGGEST_COLUMN_TEXT_1);
  18. map.put(SearchManager.SUGGEST_COLUMN_TEXT_2, City.CITY_NICKNAME + " as "+SearchManager.SUGGEST_COLUMN_TEXT_2);
  19. map.put(SearchManager.SUGGEST_COLUMN_ICON_1, City.CITY_IMG + " as "+SearchManager.SUGGEST_COLUMN_ICON_1);
  20. map.put(SearchManager.SUGGEST_COLUMN_ICON_2, City.CITY_IMG_2 + " as "+SearchManager.SUGGEST_COLUMN_ICON_2);
  21. map.put(BaseColumns._ID, "rowid AS " + BaseColumns._ID);
  22. map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
  23. return map;
  24. }
  25. @Override
  26. publicvoid onCreate(SQLiteDatabase db) {
  27. db.execSQL("create table "
  28. + City.TABLE_NAME
  29. + "(_id integer primary key autoincrement, city_id integer, city_name text, city_nickname text, city_describe text, city_img text, city_img_2 text)");
  30. }
  31. @Override
  32. publicvoid onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  33. db.execSQL("drop table if exists " + City.TABLE_NAME);
  34. onCreate(db);
  35. }
  36. /**
  37. * 用於ContentProvider調用,使用like的模糊查詢
  38. */
  39. public Cursor search(String keyWord){
  40. SQLiteQueryBuilder builder=new SQLiteQueryBuilder();
  41. builder.setTables(City.TABLE_NAME);
  42. builder.setProjectionMap(mColumnMap);
  43. SQLiteDatabase db=getReadableDatabase();
  44. return builder.query(db, columns, City.CITY_NAME + " like ? " + " or " + City.CITY_NICKNAME +" like ? ", new String[]{"%"+keyWord+"%", "%"+keyWord+"%"}, null, null,null);
  45. }
  46. }

6. 完成searchable.xml裡面注冊的ContentProvider

  1. publicclass CityContentProvider extends ContentProvider {
  2. publicstaticfinal String AUTHORITY = "com.lichen.cityprovider";
  3. private SQLiteDatabase db;
  4. private CityDatabaseHelper dbHelper;
  5. privatestaticfinalint QUERY_NORMAL= 1;
  6. privatestaticfinalint QUERY_BY_ID= 2;
  7. privatestaticfinalint QUERY_SEARCH_CITY_NAME= 3;
  8. publicstatic UriMatcher uriMatcher;
  9. static{
  10. uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
  11. uriMatcher.addURI(AUTHORITY,"city", QUERY_NORMAL);
  12. uriMatcher.addURI(AUTHORITY,"city/#", QUERY_BY_ID);
  13. uriMatcher.addURI(AUTHORITY,SearchManager.SUGGEST_URI_PATH_QUERY, QUERY_SEARCH_CITY_NAME);
  14. uriMatcher.addURI(AUTHORITY,SearchManager.SUGGEST_URI_PATH_QUERY + "/*", QUERY_SEARCH_CITY_NAME);
  15. }
  16. @Override
  17. publicboolean onCreate() {
  18. dbHelper = new CityDatabaseHelper(getContext());
  19. return dbHelper != null;
  20. }
  21. @Override
  22. public Cursor query(Uri uri, String[] projection, String selection,
  23. String[] selectionArgs, String sortOrder) {
  24. db = dbHelper.getReadableDatabase();
  25. switch (uriMatcher.match(uri)) {
  26. case QUERY_SEARCH_CITY_NAME:
  27. return dbHelper.search(selectionArgs[0]);
  28. default:
  29. thrownew IllegalArgumentException("Unknown Uri: " + uri);
  30. }
  31. }
  32. }

like模糊查詢對於大數據量效果可想而知,FTS3的支持還未嘗試,詳情參考Android SDK裡面的Samples/SearchableDictionary

相關附件下載:

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /2013年資料/6月/4日/Android SearchView 搜索框

更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11

Copyright © Linux教程網 All Rights Reserved