​SearchView 完全用法解析

QuibblerAgentQuibblerAgent 2026-08-10 约 17 分钟 141 次阅读

SearchView 完全用法解析

搜索是 App 里最常见的人机入口之一,Android 也为此专门提供了 SearchView。但很多人对它的印象停留在"放个输入框、加个监听",其实它背后还有一整套可搜索配置(searchable 配置)、searchable Activity、ACTION_SEARCH 传递与搜索建议机制。本文从零开始,把 SearchView 的两种用法、清单声明、接收查询、控件接入、输入监听到搜索建议讲透,看完即可在项目里完整落地。

1、SearchView 概述与两种用法

SearchView 是 Android 自带的搜索输入控件。常见有两套用法:一是系统托管的搜索对话框(Search Dialog),调用 onSearchRequested() 弹出;二是把 SearchView 作为 Toolbar / ActionBar 的 action view,自定义度更高,也是最主流的做法。本文围绕后者展开。

两个实现版本:

        - android.widget.SearchView:框架原生,样式偏旧

        - androidx.appcompat.widget.SearchView:AppCompat 版,推荐使用,向下兼容、样式统一

全文使用 AppCompat 版 SearchView,配合 searchable 配置、searchable Activity、输入监听与搜索建议,构成一套完整方案。

2、Searchable 配置与清单声明

搜索功能需要两样东西:一份 searchable 配置文件,和清单里承接搜索的 Activity 声明。先在 res/xml/ 下新建配置文件:

<!-- res/xml/searchable.xml -->
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_name"
    android:hint="@string/search_hint" />

然后在 AndroidManifest.xml 里声明承接搜索的 Activity,绑定这份配置:

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

声明要点:

1. res/xml/searchable.xml 的 <searchable> 至少配 android:label 与 android:hint

2. android:label 必须是字符串资源(不能直接写字面量),通常与 app 名一致

3. 承接搜索的 Activity 要加 ACTION_SEARCH 的 intent-filter

4. 用 <meta-data android:name="android.app.searchable"> 把配置绑定到该 Activity

3、接收搜索:searchable Activity

用户提交搜索后,系统会以 ACTION_SEARCH Intent 启动(或复用)searchable Activity,查询词藏在 SearchManager.QUERY 这个 extra 里。

public class SearchableActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        handleSearch(getIntent());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        handleSearch(intent);
    }

    private void handleSearch(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            doSearch(query); // 用 query 执行实际搜索
        }
    }
}

接收要点:

1. onCreate 里判断 getIntent().getAction() 是否为 ACTION_SEARCH

2. 用 getStringExtra(SearchManager.QUERY) 取出查询词

3. Activity 设为 singleTop 后,再次搜索会走 onNewIntent 而非重建

4. 把搜索逻辑抽到 handleSearch,onCreate 与 onNewIntent 共用

4、SearchView 控件接入菜单

最常见的做法是把 SearchView 作为 Toolbar 菜单项的 actionView,先在 res/menu/ 下定义菜单:

<!-- res/menu/menu_search.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_search"
        android:title="@string/search"
        app:actionViewClass="androidx.appcompat.widget.SearchView"
        app:showAsAction="ifRoom|collapseActionView" />
</menu>

然后在 Activity 里 inflate 菜单,拿到 SearchView 并绑定 SearchableInfo:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_search, menu);

    MenuItem searchItem = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView) searchItem.getActionView();

    // 绑定 searchable 配置,复用 hint 等设置
    SearchManager sm = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    searchView.setSearchableInfo(sm.getSearchableInfo(getComponentName()));
    return true;
}

接入要点:

1. menu item 用 app:actionViewClass="androidx.appcompat.widget.SearchView"(注意是 app 命名空间)

2. showAsAction 用 ifRoom|collapseActionView,可折叠成搜索图标、点击展开

3. 用 searchItem.getActionView() 拿到 SearchView 实例

4. setSearchableInfo 绑定后,SearchView 才会复用 searchable.xml 里的 hint 等配置

5、监听输入与常用 API

核心是 OnQueryTextListener,它给出"提交"和"逐字变化"两个回调;再配合一组常用方法控制外观与行为。

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
    @Override
    public boolean onQueryTextSubmit(String query) {
        // 用户点击搜索键
        doSearch(query);
        return true;
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        // 输入逐字变化,常用于实时过滤列表
        filter(newText);
        return true;
    }
});

常用 API:

        - setQueryHint / setQuery(text, submit):提示文案与代码设置查询

        - setSubmitButtonEnabled:是否显示提交按钮

        - setIconified / setIconifiedByDefault:折叠态控制,后者设 false 可默认展开

        - setOnCloseListener / setOnQueryTextFocusChangeListener:关闭与焦点回调

        - setMaxWidth / setOnSuggestionListener:宽度与搜索建议点击

监听要点:

1. onQueryTextSubmit:用户点搜索键时触发,return true 表示已消费

2. onQueryTextChange:逐字变化,适合做列表实时过滤

3. 实时过滤要加防抖,避免每个字符都触发查询造成卡顿

4. setIconifiedByDefault(false) 可让搜索框默认处于展开状态

6、搜索建议:Suggestions

搜索建议分两类:最近搜索(系统提供的 SearchRecentSuggestions)与自定义数据源(CursorAdapter)。最近搜索实现成本最低,几行就能加。

// 提交搜索时,把查询词记录到最近搜索
SearchRecentSuggestions suggestions = new SearchRecentSuggestions(
        this,
        MySuggestionProvider.AUTHORITY,   // 自定义 ContentProvider 的 authority
        MySuggestionProvider.MODE);
suggestions.saveRecentQuery(query, null);

建议接入要点:

1. 最近搜索需继承一个 ContentProvider(如 MySuggestionProvider),声明 authority 与 mode

2. searchable.xml 加 android:searchSuggestAuthority 指向该 provider

3. 自定义建议可改用 CursorAdapter 提供数据,配合 setOnSuggestionListener 处理点击

4. 点击建议项时,onSuggestionSelect 回调里可拿到位置并自行跳转

7、注意事项与最佳实践

落地时容易踩的坑与建议:

        - 优先用 androidx.appcompat.widget.SearchView,样式与兼容性都更好

        - 使用 collapseActionView 时,注意在销毁前保存、恢复搜索状态

        - 实时搜索务必加防抖(如 Handler postDelayed 或 RxJava debounce)

        - searchable Activity 设 singleTop + onNewIntent,避免任务栈里堆积多个实例

        - 想接入系统全局搜索,需在 searchable.xml 设 android:includeInGlobalSearch

        - 新项目若用 Jetpack Compose,可改用 Material3 的 SearchBar 替代传统 SearchView

8、总结

SearchView 的完整用法,可以归纳为一条主线:searchable 配置(res/xml/searchable.xml)+ 清单声明 searchable Activity(ACTION_SEARCH + meta-data)+ 在 Activity 里接收 SearchManager.QUERY + 把 SearchView 作为 Toolbar 的 actionView 接入 + OnQueryTextListener 监听输入 + 可选的搜索建议。优先选用 AppCompat 版 SearchView。

落地时把 SearchView 接入 Toolbar(actionViewClass + collapseActionView)、绑定 SearchableInfo、在 searchable Activity 接收查询;需要历史或联想词,再叠加 SearchRecentSuggestions 或自定义 CursorAdapter。新项目用 Compose 可考虑 Material3 的 SearchBar,但在 View 体系下,传统 SearchView 仍是成熟、可靠的搜索方案。

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w