在一个活动中使用SearchView,在另一个活动中显示结果。

12

我的使用案例如下:在活动A中,我有一个带有可折叠搜索视图的操作栏。当用户输入查询并按下“搜索”按钮时,我想展示结果的B活动。但我无法做到这一点,以下是我的代码:

searchable.xml:

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

活动 A:

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

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

    return true;
}

Activity A 和 B 的 AndroidManifest:

    <activity
        android:name=".ActivityA">

        <intent-filter>

            <action android:name="android.intent.action.MAIN"/>

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

        </intent-filter>

    </activity>

    <activity android:name=".ActivityB">

        <intent-filter>

            <action android:name="android.intent.action.SEARCH"/>

        </intent-filter>

        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable"/>

    </activity>
无论我尝试什么,A中的getSearchableInfo始终返回null。我感觉我没有理解某些东西。唯一能使getSearchableInfo()不返回null的方法是将SEARCH意图过滤器和可搜索元数据放入清单文件中的A活动中。但是,当我按下“搜索”按钮时,另一个A活动实例会再次在当前活动之上启动,这绝对不是我想要的。我猜我可以将singleTop添加到A,并在onNewIntent中处理SEARCH操作并启动B,但通常我不希望A成为singleTop,我想要默认的。还是我需要singleTop呢?我尝试将以下内容添加到清单文件A中(如一些其他线程中建议的):
    <meta-data
        android:name="android.app.default_searchable"
        android:value=".ActivityB" >
    </meta-data>

我做错了什么?

编辑:我在A中用以下代码替换了'getComponentName()'行:

searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(this, ActivityB.class)));

看起来这个方法能够按照我的期望工作!我是不是做错了什么,或者这就是正确的方式?我有点不确定,因为没有任何地方提到过它!


1
文档中说明getSearchableInfo(componentName)需要一个参数,即“要获取可搜索信息的活动”。在您的情况下,您需要ActivityB,因此构造指向ActivityB的ComponentName是正确的方法。 - hidro
@hidro - 如果你写一个答案,我会接受它。 - wujek
非常感谢您提出这个问题。在浪费了四个小时之后,终于得到解救。 - X09
2个回答

17
根据Android文档SearchManager.getSearchableInfo(componentName)需要一个参数,即:

componentName:要获取可搜索信息的活动

在您的情况下,您需要ActivityB,因此构建指向ActivityBComponentName是正确的方式。

new ComponentName(this, ActivityB.class)

2
就像魔法一样。我只能给一个赞,否则我会给一百万个。 - X09

0
<intent-filter>
            <action android:name="android.intent.action.SEARCH"/>
        </intent-filter>

在Activity A中添加此意图过滤器。

2.搜索视图菜单

SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView = (SearchView) menu.findItem(R.id.search).getActionView();
        searchView.setSearchableInfo(searchManager
                .getSearchableInfo(getComponentName()));

XML:

  <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/search"
        android:actionViewClass="android.widget.SearchView"
        android:icon="@drawable/ic_action_search"
        android:showAsAction="collapseActionView|always"
        android:title="@string/search_hint"/>

</menu>

3. 在oncreate中调用此方法。

private void handleIntent(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);

            Debug.e("Suggestion handle click", "call " + query);

            startNextActivity(query);

        }
    }

4. 如果您正在使用自动建议ListView,则实现searchView.setOnQueryTextListener、setOnSuggestionListener和setSuggestionsAdapter。


我不想让A获得搜索意图,这就是我的问题的全部重点,如果我没有表达清楚,对不起。 - wujek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接