Android 浮动搜索框 searchable 使用

    |     2016年2月26日   |   Android UI界面   |     0 条评论   |    1308

Android为程序的搜索功能提供了统一的搜索接口,search dialog和search widget,这里介绍search dialog使用。
search dialog 只能为于activity窗口的上方。下面以点击EditText输入框启动search dialog搜索框为例:
效果如下

search1

实现步骤:

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);
        }
}

search4

转载请注明来源:Android 浮动搜索框 searchable 使用
回复 取消