Android(安卓)SearchView 搜索框
16lz
2021-12-04
如果对这个效果感觉不错, 请往下看.
背景: 天气预报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 -->
- <!--Receivesthesearchrequest.-->
- <intent-filter>
- <actionandroid:name="android.intent.action.SEARCH"/>
- <!--Nocategoryneeded,becausetheIntentwillspecifythisclasscomponent-->
- </intent-filter>
- <!--Pointstosearchablemetadata.-->
- <meta-dataandroid:name="android.app.searchable"
- android:resource="@xml/searchable"/>
- <!-- /关注1 -->
- </activity>
- <providerandroid:name="com.lichen.db.CityContentProvider"
- android:authorities="com.lichen.cityprovider"
- android:label="@string/app_name"></provider>
- <!-- 关注2 -->
- <!--Pointstosearchableactivitysothewholeappcaninvokesearch.-->
- <meta-dataandroid:name="android.app.default_searchable"
- android:value="com.lichen.weather.WeatherActivity"/>
- <!-- /关注2 -->
- </application>
2. menu菜单里面加入
- <menuxmlns:android="http://schemas.android.com/apk/res/android">
- <itemandroid:id="@+id/search"
- android:title="@string/menu_search"
- android:showAsAction="collapseActionView|ifRoom"
- android:actionViewClass="android.widget.SearchView"/>
- </menu>
3. 然后在res目录下新建xml/searchable.xml
- <?xmlversion="1.0"encoding="utf-8"?>
- <searchablexmlns: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的protectedvoidonNewIntent(Intentintent){}来交互.
- @Override
- protectedvoidonNewIntent(Intentintent){
- handleIntent(intent);
- }
- privatevoidhandleIntent(Intentintent){
- if(Intent.ACTION_VIEW.equals(intent.getAction())){
- //查询数据库
- CursorsearchCursor=getContentResolver().query(intent.getData(),null,null,null,null);
- if(searchCursor!=null&&searchCursor.moveToFirst()){
- cityInput.setText(searchCursor.getString(searchCursor.getColumnIndex(City.CITY_DESCRIBE)));
- }
- }
- @Override
- publicbooleanonCreateOptionsMenu(Menumenu){
- getMenuInflater().inflate(R.menu.activity_weather,menu);
- SearchManagersearchManager=(SearchManager)getSystemService(Context.SEARCH_SERVICE);
- SearchViewsearchView=(SearchView)menu.findItem(R.id.search).getActionView();
- searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
- searchView.setIconifiedByDefault(false);
- returntrue;
- }
以上的在网上可以搜索到,接下来是重点...
5. 需要数据库支持
- publicclassCityDatabaseHelperextendsSQLiteOpenHelper{
- protectedstaticfinalStringDATABASE_NAME="city.db";
- protectedstaticfinalintDATABASE_VERSION=6;
- publicString[]columns=newString[]{
- 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};
- privatestaticfinalHashMap<String,String>mColumnMap=buildColumnMap();
- publicCityDatabaseHelper(Contextcontext){
- super(context,DATABASE_NAME,null,DATABASE_VERSION);
- }
- privatestaticHashMap<String,String>buildColumnMap(){
- HashMap<String,String>map=newHashMap<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,"rowidAS"+BaseColumns._ID);
- map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID,"rowidAS"+SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
- returnmap;
- }
- @Override
- publicvoidonCreate(SQLiteDatabasedb){
- db.execSQL("createtable"
- +City.TABLE_NAME
- +"(_idintegerprimarykeyautoincrement,city_idinteger,city_nametext,city_nicknametext,city_describetext,city_imgtext,city_img_2text)");
- }
- @Override
- publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){
- db.execSQL("droptableifexists"+City.TABLE_NAME);
- onCreate(db);
- }
- /**
- *用于ContentProvider调用,使用like的模糊查询
- */
- publicCursorsearch(StringkeyWord){
- SQLiteQueryBuilderbuilder=newSQLiteQueryBuilder();
- builder.setTables(City.TABLE_NAME);
- builder.setProjectionMap(mColumnMap);
- SQLiteDatabasedb=getReadableDatabase();
- returnbuilder.query(db,columns,City.CITY_NAME+"like?"+"or"+City.CITY_NICKNAME+"like?",newString[]{"%"+keyWord+"%","%"+keyWord+"%"},null,null,null);
- }
- }
6. 完成searchable.xml里面注册的ContentProvider
- publicclassCityContentProviderextendsContentProvider{
- publicstaticfinalStringAUTHORITY="com.lichen.cityprovider";
- privateSQLiteDatabasedb;
- privateCityDatabaseHelperdbHelper;
- privatestaticfinalintQUERY_NORMAL=1;
- privatestaticfinalintQUERY_BY_ID=2;
- privatestaticfinalintQUERY_SEARCH_CITY_NAME=3;
- publicstaticUriMatcheruriMatcher;
- static{
- uriMatcher=newUriMatcher(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
- publicbooleanonCreate(){
- dbHelper=newCityDatabaseHelper(getContext());
- returndbHelper!=null;
- }
- @Override
- publicCursorquery(Uriuri,String[]projection,Stringselection,
- String[]selectionArgs,StringsortOrder){
- db=dbHelper.getReadableDatabase();
- switch(uriMatcher.match(uri)){
- caseQUERY_SEARCH_CITY_NAME:
- returndbHelper.search(selectionArgs[0]);
- default:
- thrownewIllegalArgumentException("UnknownUri:"+uri);
- }
- }
- }
like模糊查询对于大数据量效果可想而知,FTS3的支持还未尝试,详情参考Android SDK里面的Samples/SearchableDictionary
更多相关文章
- android mediaStore
- Android中音乐文件的信息详解【安卓源码解析二】
- 文件浏览器
- android小程序 查询电话号码信息
- android bluetooth UUID蓝牙查询表
- Android(安卓)判断SD卡是否存在及容量查询
- android下数据库的增删改查
- android 输入框自动匹配-AutoCompleteTextView
- Android(安卓)Contacts的使用(一)