Android SearchView 搜索框
2013-05-04 00:30
423 查看
如果对这个效果感觉不错, 请往下看.
背景: 天气预报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
本文出自 “wIsper 把技术做成艺术” 博客,请务必保留此出处http://lichen.blog.51cto.com/697816/1192652
相关文章推荐
- Android搜索框(SearchView)的功能和用法详解
- Android自定义View——自定义搜索框(SearchView)
- Android的搜索框SearchView的用法-android学习之旅(三十九)
- 一个最简单的基于Android SearchView的搜索框
- Android的搜索框SearchView的用法-android学习之旅(三十九)
- Android中的搜索框(SearchView)的功能和用法
- Android搜索框SearchView属性和用法详解
- Android自定义View——自定义搜索框(SearchView)
- Android下利用ToolBar+SearchView实现仿微信搜索框效果
- (转)Android SearchView 搜索框
- Android搜索框组件SearchView的基本使用方法
- Android自定义View——自定义搜索框(SearchView)
- Android自定义View——自定义搜索框(SearchView)
- android searchView 去掉默认下划线 改为圆角搜索框
- Android 搜索框:SearchView 的属性和用法详解
- android基础-数值选择器(NumberPicker)、搜索框(SearchView)、选项卡(TabHost)、滚动视图(ScrollView)、Notification
- Android中的搜索框(SearchView)的功能和用法
- 登陆Android中的搜索框(SearchView)的功能和用法
- 一个最简单的基于Android SearchView的搜索框
- Android 搜索框:SearchView 的属性和用法详解