
若是對這個效果感受不錯, 請往下看.html
背景: 天氣預報app, 本地數據庫存儲70個大中城市的基本信息, 根據用戶輸入的或經過搜索框選取的城市, 點擊查詢按鈕後, 異步請求國家氣象局數據, 獲得返回的json解析並顯示.java
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>
-
-
-
- <intent-filter>
- <action android:name="android.intent.action.SEARCH" />
-
- </intent-filter>
-
-
- <meta-data android:name="android.app.searchable"
- android:resource="@xml/searchable" />
-
-
- </activity>
- <provider android:name="com.lichen.db.CityContentProvider"
- android:authorities="com.lichen.cityprovider"
- android:label="@string/app_name"></provider>
-
-
-
- <meta-data android:name="android.app.default_searchable"
- android:value="com.lichen.weather.WeatherActivity" />
-
-
- </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這種方式.android
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;
- }
以上的在網上能夠搜索到,接下來是重點...json
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);
- }
-
-
-
-
- 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/SearchableDictionaryapp
轉:http://blog.csdn.net/lc19850921/article/details/8887387異步