|
如果对这个效果感觉不错, 请往下看.
背景: 天气预报app, 本地数据库存储70个大中城市的基本信息, 根据用户输入的或通过搜索框选取的城市, 点击查询按钮后, 异步请求国家气象局数据, 得到返回的json解析并显示.
1. 先说AndroidManifest.xml文件- < uses-sdk
- android:minSdkVersion = "11"
- android:targetSdkVersion = "16" />
- < application >
- < activity
- android:name = "com.lichen.weather.WeatherActivity"
- android:launchMode = "singleTop"
- android:label = "@string/app_name" >
- < intent-filter >
- <!-- 省略 -->
- </ intent-filter >
- <!-- 关注1 -->
- <!-- Receives the search request. -->
- < intent-filter >
- < action android:name = "android.intent.action.SEARCH" />
- <!-- No category needed, because the Intent will specify this class component-->
- </ intent-filter >
- <!-- Points to searchable meta data. -->
- < meta-data android:name = "android.app.searchable"
- android:resource = "@xml/searchable" />
- <!-- /关注1 -->
- </ activity >
- < provider android:name = "com.lichen.db.CityContentProvider"
- android:authorities = "com.lichen.cityprovider"
- android:label = "@string/app_name" > </ provider >
- <!-- 关注2 -->
- <!-- Points to searchable activity so the whole app can invoke search. -->
- < meta-data android:name = "android.app.default_searchable"
- android:value = "com.lichen.weather.WeatherActivity" />
- <!-- /关注2 -->
- </ application >
|
2. menu菜单里面加入
- < menu xmlns:android = "http://schemas.android.com/apk/res/android" >
- < item android:id = "@+id/search"
- android:title = "@string/menu_search"
- android:showAsAction = "collapseActionView|ifRoom"
- android:actionViewClass = "android.widget.SearchView" />
- </ menu >
|
3. 然后在res目录下新建xml/searchable.xml
- <? xml version= "1.0" encoding= "utf-8" ?>
- < searchable xmlns:android= "http://schemas.android.com/apk/res/android"
- android:label= "@string/search_label"
- android:hint= "@string/search_hint"
- android:searchSuggestAuthority= "com.lichen.cityprovider"
- android:searchSuggestIntentAction= "android.intent.action.VIEW"
- android:searchSuggestIntentData= "content://com.lichen.cityprovider/city"
- android:searchSuggestSelection= " ?"
- android:searchSuggestThreshold= "1"
- android:includeInGlobalSearch= "true" >
- </ searchable >
|
字符串尽量使用 @string/search_label 这种方式.
4. Activity中
因为注册Activity的启动方式为 android:launchMode = "singleTop", 需要Activity的 protected void onNewIntent(Intent intent) {} 来交互.
- @Override
- protected void onNewIntent(Intent intent) {
- handleIntent(intent);
- }
- private void handleIntent(Intent intent) {
- if (Intent.ACTION_VIEW.equals(intent.getAction())) {
- //查询数据库
- Cursor searchCursor = getContentResolver().query(intent.getData(), null , null , null , null );
- if (searchCursor != null && searchCursor.moveToFirst()) {
- cityInput.setText(searchCursor.getString(searchCursor.getColumnIndex(City.CITY_DESCRIBE)));
- }
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.activity_weather, menu);
- SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
- SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
- searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
- searchView.setIconifiedByDefault( false );
- return true ;
- }
|
以上的在网上可以搜索到,接下来是重点...
5. 需要数据库支持
- public class CityDatabaseHelper extends SQLiteOpenHelper {
- protected static final String DATABASE_NAME = "city.db" ;
- protected static final int DATABASE_VERSION = 6 ;
- public String[] columns = new String[] {
- SearchManager.SUGGEST_COLUMN_TEXT_1,
- SearchManager.SUGGEST_COLUMN_TEXT_2,
- SearchManager.SUGGEST_COLUMN_ICON_1,
- SearchManager.SUGGEST_COLUMN_ICON_2,
- BaseColumns._ID,
- SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
- private static final HashMap<String,String> mColumnMap = buildColumnMap();
- public CityDatabaseHelper(Context context) {
- super (context, DATABASE_NAME, null , DATABASE_VERSION);
- }
- private static HashMap<String,String> buildColumnMap() {
- HashMap<String,String> map = new HashMap<String,String>();
- map.put(SearchManager.SUGGEST_COLUMN_TEXT_1, City.CITY_DESCRIBE + " as " +SearchManager.SUGGEST_COLUMN_TEXT_1);
- map.put(SearchManager.SUGGEST_COLUMN_TEXT_2, City.CITY_NICKNAME + " as " +SearchManager.SUGGEST_COLUMN_TEXT_2);
- map.put(SearchManager.SUGGEST_COLUMN_ICON_1, City.CITY_IMG + " as " +SearchManager.SUGGEST_COLUMN_ICON_1);
- map.put(SearchManager.SUGGEST_COLUMN_ICON_2, City.CITY_IMG_2 + " as " +SearchManager.SUGGEST_COLUMN_ICON_2);
- map.put(BaseColumns._ID, "rowid AS " + BaseColumns._ID);
- map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
- return map;
- }
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL( "create table "
- + City.TABLE_NAME
- + "(_id integer primary key autoincrement, city_id integer, city_name text, city_nickname text, city_describe text, city_img text, city_img_2 text)" );
- }
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.execSQL( "drop table if exists " + City.TABLE_NAME);
- onCreate(db);
- }
- /**
- * 用于ContentProvider调用,使用like的模糊查询
- */
- public Cursor search(String keyWord){
- SQLiteQueryBuilder builder= new SQLiteQueryBuilder();
- builder.setTables(City.TABLE_NAME);
- builder.setProjectionMap(mColumnMap);
- SQLiteDatabase db=getReadableDatabase();
- return builder.query(db, columns, City.CITY_NAME + " like ? " + " or " + City.CITY_NICKNAME + " like ? " , new String[]{ "%" +keyWord+ "%" , "%" +keyWord+ "%" }, null , null , null );
- }
- }
|
6. 完成searchable.xml里面注册的ContentProvider
- public class CityContentProvider extends ContentProvider {
- public static final String AUTHORITY = "com.lichen.cityprovider" ;
- private SQLiteDatabase db;
- private CityDatabaseHelper dbHelper;
- private static final int QUERY_NORMAL= 1 ;
- private static final int QUERY_BY_ID= 2 ;
- private static final int QUERY_SEARCH_CITY_NAME= 3 ;
- public static UriMatcher uriMatcher;
- static {
- uriMatcher= new UriMatcher(UriMatcher.NO_MATCH);
- uriMatcher.addURI(AUTHORITY, "city" , QUERY_NORMAL);
- uriMatcher.addURI(AUTHORITY, "city/#" , QUERY_BY_ID);
- uriMatcher.addURI(AUTHORITY,SearchManager.SUGGEST_URI_PATH_QUERY, QUERY_SEARCH_CITY_NAME);
- uriMatcher.addURI(AUTHORITY,SearchManager.SUGGEST_URI_PATH_QUERY + "/*" , QUERY_SEARCH_CITY_NAME);
- }
- @Override
- public boolean onCreate() {
- dbHelper = new CityDatabaseHelper(getContext());
- return dbHelper != null ;
- }
- @Override
- public Cursor query(Uri uri, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- db = dbHelper.getReadableDatabase();
- switch (uriMatcher.match(uri)) {
- case QUERY_SEARCH_CITY_NAME:
- return dbHelper.search(selectionArgs[ 0 ]);
- default :
- throw new IllegalArgumentException( "Unknown Uri: " + uri);
- }
- }
- }
|
like模糊查询对于大数据量效果可想而知,FTS3的支持还未尝试,详情参考Android SDK里面的Samples/SearchableDictionary
附件:http://down.51cto.com/data/2362766
----------------------------
原文链接:https://blog.51cto.com/lichen/1192652
程序猿的技术大观园:www.javathinker.net
[这个贴子最后由 flybird 在 2020-04-08 09:35:55 重新编辑]
|
|