android浮动搜索框的使用

引言

在我们的应用程序中经常需要提供搜索服务,比如搜索联系人, 搜索商品信息等等。我们可以自己在布局中自定义我们的搜索框,实现我们的搜索逻辑。但是还有一种更简单的方法:使用android系统给我们提供的搜索功能框架。

在android中,提供两种实现搜索功能的方式:search dialog 和 searchView.

search dialog类似于普通的dialog,悬浮于我们的窗体之上。示例图如下:

searchView通常被嵌套在我们的布局之中,最典型的案例就是在actionBar中使用searchView.下图是searchView在微信中的使用。(PS:图中的放大镜就是searchView)

不管你使用哪种方式,安卓系统都会发送查询请求到处理搜索逻辑的activity中,来实现搜索功能。

另外,除了普通的文字搜索外,还提供了一下的搜索功能:

1.语音搜索

2.最近搜索记录提示

3.自定义搜索记录提示

4.google系统搜索框

google系统搜索框

需要注意的是:安卓系统并不会提供搜索逻辑,也就是说,当系统将搜索关键字传递给我们的时候,需要我们自己来处理搜索逻辑。比如在数据库中搜索、在网络中搜索。

另外,安卓系统也不会显式地调用我们的搜索框,我们需要自己调用方法来显示我们的搜索框。

今天我们主要介绍search dialog的使用方式。

基本原理

首先我们来了解一下系统搜索功能的基本原理。

(一)当用户在搜索框中执行搜索操作后,系统会自动创建一个Intent,并且将用户搜索的关键字存放到Intent中。

(二)系统会启动处理搜索逻辑的activity(通常可以命名为SearchableActivity)并将intent传递给SearchableActivity,然后在SearchableActivity中处理我们的搜索逻辑。

配置搜索框

第一步,我们需要配置我们搜索框的xml文件,其中包括一些属性比如:语音搜索,搜索提示和搜索记录等等。

配置文件通常命名为searchable.xml 并且必须 存放在我们工程的res/xml目录中(没有就创建一个)

(PS:系统使用这个配置文件来实例化SearchableInfo对象,这个对象是提供搜索相关的元数据的,比如SearchableActivity的类名,搜索关键字的类型等等。但是我们不能自己实例化SearchableInfo 对象,只能通过配置文件的方式来设置)

下面是searchable.xml配置文件的内容

searchable.xml

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:hint="@string/searchHint"
    android:label="@string/searchLabel" >
</searchable>

配置文件的根节点必须是searchable ,其中label是必须的,它的值为一个string资源引用,通常是应用程序的名称(尽管它是一个必须的属性,但通常情况下是不显示出来的,除非你开启了搜索建议功能)。

android:hint是配置搜索框的输入提示信息,虽然不是必须的属性,但是强烈建议设置这个属性,以便用户输入搜索信息的时候,可是知道能输入那些搜索信息。

以配置很多的属性,但大部分属性都只是在使用搜索建议和语音搜索时进行配置。

SearchableActivity

第二步, 我们创建SearchableActivity来处理搜索逻辑并且显示搜索结果。

我们需要在android-manifest.xml文件中配置SearchableActivity的一些属性,来将它指定为处理搜索逻辑的activity

android-manifest.xml

<application ... >
    <activity android:name=".SearchableActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
    </activity>
    ...
</application>

首先在intent-filter节点中添加 ACTION_SEARCH的action。然后再meta-data节点中的name属性必须为android.app.searchable,resource属性为我们的配置文件searchable.xml

注意:我们并不需要在intent-filter中配置category,因为SearchManager会根据SearchableActivity的componentName,显示地传递数据给它。

查看下列SearchManager.class的源码,我们可以知道这是怎么实现的。

SearchManager.class

 /**
     * Starts the global search activity.
     */
    /* package */ void startGlobalSearch(String initialQuery, boolean selectInitialQuery,
            Bundle appSearchData, Rect sourceBounds) {
            //这是我们的searchableActivity
        ComponentName globalSearchActivity = getGlobalSearchActivity();
        if (globalSearchActivity == null) {
            Log.w(TAG, "No global search activity found.");
            return;
        }
        Intent intent = new Intent(INTENT_ACTION_GLOBAL_SEARCH);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //显示传递
        intent.setComponent(globalSearchActivity);
        // Make sure that we have a Bundle to put source in
        if (appSearchData == null) {
            appSearchData = new Bundle();
        } else {
            appSearchData = new Bundle(appSearchData);
        }
        // Set source to package name of app that starts global search, if not set already.
        if (!appSearchData.containsKey("source")) {
            appSearchData.putString("source", mContext.getPackageName());
        }
        //查询的数据
        intent.putExtra(APP_DATA, appSearchData);
        if (!TextUtils.isEmpty(initialQuery)) {
            intent.putExtra(QUERY, initialQuery);
        }
        if (selectInitialQuery) {
            intent.putExtra(EXTRA_SELECT_QUERY, selectInitialQuery);
        }
        intent.setSourceBounds(sourceBounds);
        try {
            if (DBG) Log.d(TAG, "Starting global search: " + intent.toUri(0));
            mContext.startActivity(intent);
        } catch (ActivityNotFoundException ex) {
            Log.e(TAG, "Global search activity not found: " + globalSearchActivity);
        }
    }

一般而言,查询到的数据都是通过一个ListView来展示的,所以,我们可以让SearchableActivity继承ListActivity来方便操作。

在SearchableActivity中,我们需要完成三件事:

1.接受查询参数

当用户执行搜索操作的时候,系统通过intent传递名为QUERY 的数据,其中包含的就是我们的搜索关键字,我们可以在intent中接受QUERY数据

public class SearchActivity extends ListActivity
{
            //测试数据
    private String[][] datas = { { "activity", "actionbar", "animation", "android" },
            { "bundle", "block", "bluetooth", "boolean" } };
            //查询结果
    private String[] result;
    private Intent intent;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);

    intent = getIntent();
        // 判断是否是搜索请求
        if (Intent.ACTION_SEARCH.equals(intent.getAction()))
        {
            // 获取搜索的查询内容(关键字)
            String query = intent.getStringExtra(SearchManager.QUERY);

2.根据查询参数查询数据

获取到查询关键字query后,我们就可以执行我们的查询逻辑了。

    // 执行相应的查询动作
            boolean isSuccess =queryContact(query);
private boolean queryContact(String query)
    {
        for (String[] ss : datas)
        {
            for (String s : ss)
            {
                if (s.contains(query)){
                    result = ss;
                    return true;
                }
            }
        }
        return false;
    }

queryContact方法是我写的模拟查询字典的方法。这里可以换成在数据库或者网络中查询数据。

3.显示查询到的数据

查询到数据中,我们需要将数据显示到ListView中,并且当用户点击某一查询结果时,将查询结果返回给MainActivity.

intent = new Intent(SearchActivity.this, MainActivity.class);
            if(isSuccess){
                setListAdapter(new ArrayAdapter<>(this,
                        android.R.layout.simple_list_item_1, result));
                getListView().setOnItemClickListener( new OnItemClickListener()
                {

                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id)
                    {

                        intent.putExtra("name", result[position]);
                        startActivity(intent);
                    }

                });

            }else{
            Toast.makeText(this, "没有查询到数据", Toast.LENGTH_SHORT).show();
            startActivity(intent);
            }
        }
    }

使用搜索框

最后,我们就需要在MainActivity中使用我们的搜索框了。由于前面说过,搜索框默认情况下是隐藏的,需要我们自己来调用。在调用之前,我们还需要在manifest文件中进行配置,指定使用searchableActivity.

  <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
                <!-- enable the search dialog to send searches to SearchableActivity -->
        <meta-data android:name="android.app.default_searchable"
                   android:value=".SearchActivity" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

在MianActivity的节点中,我们需要配置meta-data节点,name必须指定为android.app.default_searchable,value表示我们的searchableActivity.

如果想将搜索框指定为全局的,在整个application中都能使用,那就将meta-data节点配置在application节点中。

最后,我们在MainActivity中调用搜索框。

由于不同的设备的物理按键有很大的差异,有些手机有物理的搜索按键,而有些手机是没有的。所以我们最好自己在activity中通过一个搜索按钮来显式的调用搜索框。另外一种方法是,通过手机软键盘上面的搜索按钮来调用搜索框,这需要在OnCreate()中调用 setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL) .

搜索框是一个悬浮于屏幕上的dialog。它不会对activity栈和生命周期引起任何变化。所以当搜索框出现的时候,没有任何如onPause()的方法被调用。

通过调用onSearchRequested()方法,我们来激活搜索框。

在MainActivity中,我们点击button来显示搜索框,执行搜索后,将获取到的搜索结果显示在TextView中。

MainActivity.class

public class MainActivity extends ActionBarActivity
{
    private TextView msg;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        msg=(TextView) findViewById(R.id.msg);

    }
    @Override
    protected void onResume()
    {

        String name =(String) getIntent().getStringExtra("name");
        if(name!=null)
        msg.setText(name);
        super.onResume();
    }
    public void search(View view)
    {
        onSearchRequested();
    }

}

另外,我们也可以重写onSearchRequested()方法,在搜索的同时做一些其他的操作,比如暂停音乐播放等等。

@Override
public boolean onSearchRequested() {
    pauseMusic();
    return super.onSearchRequested();
}

另外,如果我们需要对查询关键字加一些限制条件的时候,我们可以调用onSearchRequested()发送一些额外的数据给searchableActivity,searchableActivity中进行处理。

@Override
public boolean onSearchRequested() {
//查询参数
     Bundle appData = new Bundle();
     appData.putBoolean(SearchableActivity.JARGON, true);
     startSearch(null, false, appData, false);
     return true;
 }

当searchableActivity接受到传递的查询参数和关键字时,就可以进行查询操作了。

//通过SearchManager.APP_DATA来提取数据
Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
if (appData != null) {
    boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
  //下面这一句表示我们可以进行的操作。。。。
  // “select * from ... where word=query and ...=jargon”;
}

注意:我们不能再onSearchRequested()方法外调用startSearch方法,任何操作都必须通过onSearchRequested()来调用。

本文参考自android官网:https://developer.android.com/guide/topics/search/search-dialog.html

源码下载

时间: 2024-10-11 10:40:31

android浮动搜索框的使用的相关文章

android浮动搜索框

android浮动搜索框的配置比较繁琐,需要配置好xml文件才能实现onSearchRequest()方法. 1.配置搜索的XML配置文件?,新建文件searchable.xml,保存在res/xml文件夹中. 1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <searchable android:label="@string/search_label" 4 android:search

Android actionbar 搜索框

就是实现在顶部这样的搜索框. 一.这个搜索框是actionbar上的menu上的一个item.叫SearchView.我们可以先在menu选项里定义好: bmap_menu.xml: <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item androi

Android学习笔记_79_ Android 使用 搜索框

1.在资源文件夹下创建xml文件夹,并创建一个searchable.xml: <?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/sms_search" android:hint="@st

Android实现搜索框内自动完成文本框

Android实现搜索框内自动完成文本框 xml文件代码如下: 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:orientation="vertical" 5 android:layout_width=

Xamarin Android 的搜索框 : Search Dialog

Android 的搜索有两种可用方式: Search Dialog它是一个 UI Component , 被激活的时候, 会在顶部显示一个浮动的搜索框. SearchView  可以被布局到任何地方.在 Android 3.0 (Level 11) 中提供. SearchView 简单,随意使用,这里主要说说 Search Dialog  的基本用法, 因为 Xamarin 的处理方式稍稍和 原生 Android 有些不同. 效果: 源码: https://github.com/gruan01/

Android自定义搜索框

搜索框里的虚拟键盘 xml如下 <EditText android:id="@+id/et_shopshow_search" android:layout_width="144dp" android:layout_height="40dp" android:singleLine="true" android:paddingLeft="8dp" android:paddingRight="8d

Android的搜索框SearchView的用法-android学习之旅(三十九)

SearchView简介 SearchView是搜索框组件,他可以让用户搜索文字,然后显示.' 代码示例 这个示例加了衣蛾ListView用于为SearchView增加自动补全的功能. package peng.liu.test; import android.app.Activity; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.os.Bundle; impor

Xamarin.Android 制作搜索框

前段时间仿QQ做了一个搜索框样式,个人认为还不错,留在这里给大家做个参考,希望能帮助到有需要的人. 首先上截图(图1:项目中的样式,图2:demo样式): 不多说直接上代码: Main.axml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" androi

Android零基础入门第62节:搜索框组件SearchView

原文:Android零基础入门第62节:搜索框组件SearchView 一.SearchView概述 SearchView是搜索框组件,它可以让用户在文本框内输入文字,并允许通过监听器监控用户输入,当用户输入完成后提交搜索时,也可通过监听器执行实际的搜索. SearchView默认是展示一个search的icon,点击icon展开搜索框,也可以自己设定图标.用SearchView时可指定如下表所示的常见XML属性及相关方法. 如果为SearchView增加一个配套的ListView,则可以为Se