Android SearchView 搜索框

简介:

效果图

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

背景: 天气预报app, 本地数据库存储70个大中城市的基本信息, 根据用户输入的或通过搜索框选取的城市, 点击查询按钮后, 异步请求国家气象局数据, 得到返回的json解析并显示.

 

1. 先说AndroidManifest.xml文件

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

2. menu菜单里面加入

 
  1. <menu xmlns:android="http://schemas.android.com/apk/res/android" > 
  2.  
  3.     <item android:id="@+id/search" 
  4.           android:title="@string/menu_search" 
  5.           android:showAsAction="collapseActionView|ifRoom" 
  6.           android:actionViewClass="android.widget.SearchView" /> 
  7.  
  8. </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的protected void onNewIntent(Intent intent) {}来交互.

 
  1. @Override 
  2. protected void onNewIntent(Intent intent) { 
  3.     handleIntent(intent); 
  4.  
  5. private void handleIntent(Intent intent) { 
  6.        if (Intent.ACTION_VIEW.equals(intent.getAction())) { 
  7.            //查询数据库 
  8.            Cursor searchCursor = getContentResolver().query(intent.getData(), nullnullnullnull); 
  9.            if (searchCursor != null && searchCursor.moveToFirst()) { 
  10.             cityInput.setText(searchCursor.getString(searchCursor.getColumnIndex(City.CITY_DESCRIBE))); 
  11.         } 
  12.    } 
  13.  
  14. @Override 
  15. public boolean onCreateOptionsMenu(Menu menu) { 
  16.     getMenuInflater().inflate(R.menu.activity_weather, menu); 
  17.      
  18.     SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); 
  19.     SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView(); 
  20.     searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); 
  21.     searchView.setIconifiedByDefault(false); 
  22.     return true

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

5. 需要数据库支持

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

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

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

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



本文转自chainli 51CTO博客,原文链接:http://blog.51cto.com/lichen/1192652,如需转载请自行联系原作者

 

相关文章
|
XML Android开发 数据格式
android平滑动画效果--搜索框
android平滑动画效果--搜索框
309 0
android平滑动画效果--搜索框
|
5月前
|
XML 数据库 Android开发
[Android]搜索框SearchView
[Android]搜索框SearchView
38 0
|
10月前
|
存储 XML JSON
简简单单搞一个实用的Android端搜索框
效果很常见,就是平常需求中的效果,上面是搜索框,下面是最近和热门搜索列表,为了方便大家在实际需求中使用,配置了很多属性,也进行了上下控件的拆分,也就是上边搜索框和下面的搜索列表的拆分,可以按需进行使用。
120 0
|
Android开发
Android 7.1 Launcher3 删除主页搜索框
Android 7.1 Launcher3 删除主页搜索框
168 0
Android 7.1 Launcher3 删除主页搜索框
|
XML 开发工具 Android开发
Android自定义控件(十三)——实现CSDN搜索框文字提示容器
Android自定义控件(十三)——实现CSDN搜索框文字提示容器
267 0
Android自定义控件(十三)——实现CSDN搜索框文字提示容器
|
Android开发
Android搜索控件SearchView
由于项目很多地方需要搜索框,就自定义了一个SearchView控件,顺便复习下自定义View的操作。 一.复用性 虽然我自己在多个地方进行复制粘贴也很省时,但是总觉得这样的做法太Low了,所以还是抽出来自定义一个view,看看效果。
999 0
|
Android开发 Go
android.support.v7.widget.SearchView开发记录(一)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qingfeng812/article/details/51548722 android.
1017 0
|
Android开发
Android AppCompatActivity的ActionBar之SearchView、ShareActionProvider以及menu
 Android AppCompatActivity的ActionBar之SearchView、ShareActionProvider以及menu Android早期推出的ActionBarActivity被Android谷歌官方废弃,推荐使用AppCompatActivity替代ActionBarActivity。
1085 0