如果对这个效果感觉不错, 请往下看.

背景: 天气预报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. <!--Receivesthesearchrequest.-->
  14. <intent-filter>
  15. <actionandroid:name="android.intent.action.SEARCH"/>
  16. <!--Nocategoryneeded,becausetheIntentwillspecifythisclasscomponent-->
  17. </intent-filter>
  18. <!--Pointstosearchablemetadata.-->
  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. <!--Pointstosearchableactivitysothewholeappcaninvokesearch.-->
  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. <?xmlversion="1.0"encoding="utf-8"?>
  2. <searchablexmlns: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的protectedvoidonNewIntent(Intentintent){}来交互.

        
  1. @Override
  2. protectedvoidonNewIntent(Intentintent){
  3. handleIntent(intent);
  4. }
  5. privatevoidhandleIntent(Intentintent){
  6. if(Intent.ACTION_VIEW.equals(intent.getAction())){
  7. //查询数据库
  8. CursorsearchCursor=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. publicbooleanonCreateOptionsMenu(Menumenu){
  15. getMenuInflater().inflate(R.menu.activity_weather,menu);
  16. SearchManagersearchManager=(SearchManager)getSystemService(Context.SEARCH_SERVICE);
  17. SearchViewsearchView=(SearchView)menu.findItem(R.id.search).getActionView();
  18. searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
  19. searchView.setIconifiedByDefault(false);
  20. returntrue;
  21. }

以上的在网上可以搜索到,接下来是重点...

5. 需要数据库支持

        
  1. publicclassCityDatabaseHelperextendsSQLiteOpenHelper{
  2. protectedstaticfinalStringDATABASE_NAME="city.db";
  3. protectedstaticfinalintDATABASE_VERSION=6;
  4. publicString[]columns=newString[]{
  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. privatestaticfinalHashMap<String,String>mColumnMap=buildColumnMap();
  12. publicCityDatabaseHelper(Contextcontext){
  13. super(context,DATABASE_NAME,null,DATABASE_VERSION);
  14. }
  15. privatestaticHashMap<String,String>buildColumnMap(){
  16. HashMap<String,String>map=newHashMap<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,"rowidAS"+BaseColumns._ID);
  22. map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID,"rowidAS"+SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
  23. returnmap;
  24. }
  25. @Override
  26. publicvoidonCreate(SQLiteDatabasedb){
  27. db.execSQL("createtable"
  28. +City.TABLE_NAME
  29. +"(_idintegerprimarykeyautoincrement,city_idinteger,city_nametext,city_nicknametext,city_describetext,city_imgtext,city_img_2text)");
  30. }
  31. @Override
  32. publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){
  33. db.execSQL("droptableifexists"+City.TABLE_NAME);
  34. onCreate(db);
  35. }
  36. /**
  37. *用于ContentProvider调用,使用like的模糊查询
  38. */
  39. publicCursorsearch(StringkeyWord){
  40. SQLiteQueryBuilderbuilder=newSQLiteQueryBuilder();
  41. builder.setTables(City.TABLE_NAME);
  42. builder.setProjectionMap(mColumnMap);
  43. SQLiteDatabasedb=getReadableDatabase();
  44. returnbuilder.query(db,columns,City.CITY_NAME+"like?"+"or"+City.CITY_NICKNAME+"like?",newString[]{"%"+keyWord+"%","%"+keyWord+"%"},null,null,null);
  45. }
  46. }

6. 完成searchable.xml里面注册的ContentProvider

        
  1. publicclassCityContentProviderextendsContentProvider{
  2. publicstaticfinalStringAUTHORITY="com.lichen.cityprovider";
  3. privateSQLiteDatabasedb;
  4. privateCityDatabaseHelperdbHelper;
  5. privatestaticfinalintQUERY_NORMAL=1;
  6. privatestaticfinalintQUERY_BY_ID=2;
  7. privatestaticfinalintQUERY_SEARCH_CITY_NAME=3;
  8. publicstaticUriMatcheruriMatcher;
  9. static{
  10. uriMatcher=newUriMatcher(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. publicbooleanonCreate(){
  18. dbHelper=newCityDatabaseHelper(getContext());
  19. returndbHelper!=null;
  20. }
  21. @Override
  22. publicCursorquery(Uriuri,String[]projection,Stringselection,
  23. String[]selectionArgs,StringsortOrder){
  24. db=dbHelper.getReadableDatabase();
  25. switch(uriMatcher.match(uri)){
  26. caseQUERY_SEARCH_CITY_NAME:
  27. returndbHelper.search(selectionArgs[0]);
  28. default:
  29. thrownewIllegalArgumentException("UnknownUri:"+uri);
  30. }
  31. }
  32. }

like模糊查询对于大数据量效果可想而知,FTS3的支持还未尝试,详情参考Android SDK里面的Samples/SearchableDictionary

更多相关文章

  1. android mediaStore
  2. Android中音乐文件的信息详解【安卓源码解析二】
  3. 文件浏览器
  4. android小程序 查询电话号码信息
  5. android bluetooth UUID蓝牙查询表
  6. Android(安卓)判断SD卡是否存在及容量查询
  7. android下数据库的增删改查
  8. android 输入框自动匹配-AutoCompleteTextView
  9. Android(安卓)Contacts的使用(一)

随机推荐

  1. LayoutInflater的用法
  2. Android(安卓)Studio如何导入第三方工程
  3. 安卓开发学习之解决JS不能调用Android方
  4. Android中使用Bundle交换数据
  5. Android(安卓)v22.0.1+ 关联 libs/*.jar
  6. android 二进制流保存为bmp文件
  7. Android(安卓)Note - Broadcast Receiver
  8. Android(安卓)JNI学习笔记(三)-编译文件Andr
  9. 命令行修改Android(安卓)id
  10. Android(安卓)NDK 应用 Clang 编译器