Android SearchView 搜尋方塊

來源:互聯網
上載者:User

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

背景: 天氣預報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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.