Android 浮动搜索框 searchable 使用
Android为程序的搜索功能提供了统一的搜索接口,search dialog和search widget,这里介绍search dialog使用。
search dialog 只能为于activity窗口的上方。下面以点击EditText输入框启动search dialog搜索框为例:
效果如下
实现步骤:
1. 新建searchable.xml配置文件,放在res/xml目录下。
searchable.xml用于配置搜索框相关属性,配置文件内容为:
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:hint="@string/search_hint"/>
注:android:lable是唯一必须定义的属性。它指向一个字符串,是应用程序的名字。
实际上该label也只有在search suggestions for Quick Search Box可用时才可见。
android:hint属性不是必须,但是还是推荐总是定义它。它是search box用户输入前输入框中的提示语。
其它属性可以查看google官方文档:
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="string resource" android:hint="string resource" android:searchMode=["queryRewriteFromData" | "queryRewriteFromText"] android:searchButtonText="string resource" android:inputType="inputType" android:imeOptions="imeOptions" android:searchSuggestAuthority="string" android:searchSuggestPath="string" android:searchSuggestSelection="string" android:searchSuggestIntentAction="string" android:searchSuggestIntentData="string" android:searchSuggestThreshold="int" android:includeInGlobalSearch=["true" | "false"] android:searchSettingsDescription="string resource" android:queryAfterZeroResults=["true" | "false"] android:voiceSearchMode=["showVoiceSearchButton" | "launchWebSearch" | "launchRecognizer"] android:voiceLanguageModel=["free-form" | "web_search"] android:voicePromptText="string resource" android:voiceLanguage="string" android:voiceMaxResults="int" > <actionkey android:keycode="KEYCODE" android:queryActionMsg="string" android:suggestActionMsg="string" android:suggestActionMsgColumn="string" > </searchable>
2. 在AndroidManifest.xml文件中声明Searchable Activity。
Searchable Activity为搜索结果显示Activity,可以定义为搜索框所在的当前Activity,也可以单独定义一个Activity
这里直接定义当前搜索框所在SearchActivity.配置如下:
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <meta-data android:name="android.app.default_searchable" android:value=".SearchActivity"/> <activity android:name=".SearchActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity> </application>
注:activity标签内的标签必须包括android:name这个属性,而且其值必须为”android.app.searchable”,
还必须包括android:resource这个属性,它指定了我们的search dialog的配置文件。(res/xml/searchable.xml).
3.启动搜索框search dailog:
在activity中调用onSearchRequested()方法
@Override public void onClick(View v) { switch (v.getId()){ case R.id.search_edit: onSearchRequested(); break; } }
如果你要在执行搜索时,进行别的操作,可以重写onSearchRequested()方法 如下:
@Override public boolean onSearchRequested() { //这个方法中干你想干的事 doSometingOther(); return super.onSearchRequested(); }
还有如果我们想在调用的时候传递一些参数 也是可以的
public boolean onSearchRequested() { Log.i(TAG,"onSearchRequested------------========"); Bundle appData = new Bundle(); appData.putString("key", "your info"); startSearch(null, true, appData, false); return true; }
4. 获取搜索关键字
搜索框中输入的搜索关键字通过下面代码可以取到:
String query = intent.getStringExtra(SearchManager.QUERY);
但在获取前应该先判断Intent中action是否为搜索action:”android.intent.action.SEARCH”
Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); }
5.搜索结果处理方式
在前面已经提过,搜索结果可以在单独一个类里处理,也可以在当前搜索框所在类处理,如果在当前搜索框所在类处理,需设置当前类为SingTop模式,防止再次创建Activity. 但这样又会引发一个问题,搜索时onCreate方法不会在执行,而在可以执行的onResult方法中得到的Intent不包含搜索Action:”android.intent.action.SEARCH”,而是原来的Action。
这说明搜索执行后Intent已经被改变,Activity中通过getIntent()取到的Intent还是原来的Intent。那么被改变的Intent从那里获取呢?
重写 onNewIntent(Intent intent) 获取,执行 setIntent(intent) 更新Activity中Intent,
@Override protected void onNewIntent(Intent intent) { setIntent(intent); } @Override protected void onResume() { super.onResume(); if (getIntent().ACTION_SEARCH.equals(getIntent().getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); } }
综上在当前搜索框所在类获取搜索关键字处理搜索结果可以这样写:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_search_dialog_layout); mSearchEdit = (EditText) findViewById(R.id.search_edit); mContentTxt = (TextView)findViewById(R.id.search_content_txt); mSearchEdit.setOnClickListener(this); handleIntent(getIntent()); } /** * 重复刷新当前Activity时执行 * @param intent */ @Override protected void onNewIntent(Intent intent) { setIntent(intent); handleIntent(intent); } private void handleIntent(Intent intent) { if (getIntent().ACTION_SEARCH.equals(getIntent().getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); doMySearch(query); } } /** * 处理搜索结果 */ public void doMySearch(String query){ mContentTxt.setText(query); }
6、纪录搜索历史关键字
我们在查询完成后会希望保存这次查询的条件 甚至有的会连结果都保存了android这里实现了保存关键字的功能
是通SearchRecentSuggestionsProvider 来实现的
首先创建一个Provider类
public class SearchSuggestionProvider extends SearchRecentSuggestionsProvider { final static String AUTHORITY = "com.debby.googlemap.SuggestionProvider"; final static int MODE = DATABASE_MODE_QUERIES; public SearchSuggestionProvider() { super(); setupSuggestions(AUTHORITY, MODE); } }
当然还要在 Manifest中配置
<provider android:name="com.debby.googlemap.SearchSuggestionProvider" android:authorities="com.debby.googlemap.SuggestionProvider" />
这里注意 android:authorities 的配置与Provider里的保持一致就好了
这样在Acitivity里就可以调用了
SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE); suggestions.saveRecentQuery(query, null);
保存完成了 点击搜索完成后保存成功了 下次搜索就可以看到
7.清空搜索历史关键字
重写SearchRecentSuggestionsProvider的query查询方法 在查询得到Cursor中添加一条”清空记录项”
@Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal) { String[] items = null; Cursor cursor = super.query(uri, projection, selection, selectionArgs, sortOrder); int arrayLength = cursor.getCount(); if (arrayLength != 0) { items = new String[arrayLength + 1]; cursor.moveToFirst(); int i = 0; for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { int number = cursor.getColumnIndex("suggest_intent_query"); items[i] = cursor.getString(number); i++; } items[i] = "清空历史记录"; }else { return null; } String[] columns = new String[]{"suggest_format", "suggest_text_1", "suggest_intent_query", "_id"}; MatrixCursor stringCursor = new MatrixCursor(columns); String row[] = new String[4]; int i = 0; for (CharSequence item : items) { row[0] = "" + 0; row[1] = item.toString(); row[2] = item.toString(); row[3] = "" + (++i); stringCursor.addRow(row); } }
转载请注明来源:Android 浮动搜索框 searchable 使用