>>分享Android开发相关的技术 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 19426 个阅读者 刷新本主题
 * 贴子主题:  Android SearchView 搜索框 回复文章 点赞(0)  收藏  
作者:sunshine    发表时间:2020-03-31 20:00:46     消息  查看  搜索  好友  邮件  复制  引用

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

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

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

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

        2. menu菜单里面加入

  1.    < menu   xmlns:android = "http://schemas.android.com/apk/res/android"   >  
  2.        < item   android:id = "@+id/search"  
  3.              android:title = "@string/menu_search"  
  4.              android:showAsAction = "collapseActionView|ifRoom"  
  5.              android:actionViewClass = "android.widget.SearchView"   />  
  6.    </ 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(),  null ,  null ,  null ,  null );
  9.               if  (searchCursor !=  null  && searchCursor.moveToFirst()) {
  10.               cityInput.setText(searchCursor.getString(searchCursor.getColumnIndex(City.CITY_DESCRIBE)));
  11.           }
  12.      }
  13.    @Override  
  14.    public   boolean  onCreateOptionsMenu(Menu menu) {
  15.       getMenuInflater().inflate(R.menu.activity_weather, menu);
  16.       SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
  17.       SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
  18.       searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
  19.       searchView.setIconifiedByDefault( false );
  20.        return   true ;
  21.   }

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

            5. 需要数据库支持

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

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

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

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

                  
附件:http://down.51cto.com/data/2362766
----------------------------
原文链接:https://blog.51cto.com/lichen/1192652

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-04-08 09:35:55 重新编辑]
  Java面向对象编程-->集合(上)
  JavaWeb开发-->Web运作原理(Ⅰ)
  JSP与Hibernate开发-->第一个helloapp应用
  Java网络编程-->用Spring整合CXF发布Web服务
  精通Spring-->CSS过渡和动画
  Vue3开发-->Vue组件开发基础
  Android打包为aab教程
  Android Service的用法
  Android 滚动Tab
  Android那些事儿之LBS定位
  Android网络开发-创建请求队列
  Android静默安装的实现
  Android自定义组件
  Android--Widget开发
  Android语音识别 android.speech 包分析
  Android ListView高度问题
  Android 性能优化之渲染原理
  Android使用讯飞SDK开发语音识别及合成小Demo
  Android 自定义View实现圆形进度条 深入理解onDraw和onMeasu...
  Android 自定义九宫格手势锁
  Android 之不要滥用 SharedPreferences(上)
  更多...
 IPIP: 已设置保密
树形列表:   
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。