是否可以仅使用搜索小部件(SearchView)传递搜索上下文数据? [英] Is it possible to pass search context data using the Search Widget (SearchView) only?

查看:110
本文介绍了是否可以仅使用搜索小部件(SearchView)传递搜索上下文数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据官方文档,提供搜索界面的两种方法:使用搜索对话框或SearchView小部件.我想注意使用这两种方式传递搜索上下文数据.

According to the official documentation, there are two ways of providing a search interface: using either the search dialog or a SearchView widget. I'd like to pay attention to passing search context data using these two ways.

因此,文档说:

So, the documentation says:

..您可以提供系统发送到的意图的其他数据 您的可搜索活动.您可以在 APP_DATA捆绑包,包含在ACTION_SEARCH目的中.

..you can provide additional data in the intent that the system sends to your searchable activity. You can pass the additional data in the APP_DATA Bundle, which is included in the ACTION_SEARCH intent.

要将此类数据传递给您的可搜索活动,请覆盖 用户可以从中进行活动的onSearchRequested()方法 执行搜索,使用其他数据创建捆绑包,然后调用 startSearch()激活搜索对话框.例如:

To pass this kind of data to your searchable activity, override the onSearchRequested() method for the activity from which the user can perform a search, create a Bundle with the additional data, and call startSearch() to activate the search dialog. For example:

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

..一旦用户提交查询,该查询就会传递给您的可搜索内容 活动以及您添加的数据.您可以提取额外的 来自APP_DATA捆绑包的数据以优化搜索.例如:

..Once the user submits a query, it's delivered to your searchable activity along with the data you've added. You can extract the extra data from the APP_DATA Bundle to refine the search. For example:

Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
if (appData != null) {
    boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
}

这是指搜索对话框.那搜索小部件呢?

This refers to the search dialog. And what about the search widget?

是否可以仅使用SearchView小部件传递搜索上下文数据?

Is it possible to pass search context data using the SearchView widget only?

希望,有人可以给出清晰的解释和/或提出另一种或类似的方式来实现目标.

Hope, someone could give clear explanation and/or suggest another or similar way to accomplish the goal.

谢谢!

推荐答案

我已经找到了解决方案.甚至两个解决方案!

I've discovered the solution. Even two solutions!

他们不需要调用onSearchRequested(),因此根本没有搜索对话框:)

They don't need to invoke onSearchRequested() thus there is no search dialog at all :)

首先,我提供了一些通用的步骤来创建搜索界面,然后给出源问题的解决方案.

First, I provide some common steps to create the search interface and then give the solutions of the source problem.

我们通过使用以下代码创建res/menu/options_menu.xml文件,将搜索视图添加到应用栏:

We add the Search View to the App Bar by creating res/menu/options_menu.xml file with the following code:

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

    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_action_search"
        android:title="@string/search_string"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="android.support.v7.widget.SearchView" />

</menu>

res/xml/searchable.xml文件中创建可搜索的配置:

Create a Searchable Configuration in res/xml/searchable.xml file:

<?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" />

AndroidManifest.xml中声明两个活动:

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

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <activity android:name=".SearchableActivity"
            android:label="@string/app_name"
            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>

    </application>

</manifest>

创建一个可搜索活动,我们在其中处理ACTION_SEARCH意图和从MainActivity传递的搜索上下文数据.我们从APP_DATA Bundle中提取额外的数据以完善搜索范围:

Create a Searchable Activity where we handle the ACTION_SEARCH intent and the search context data, passed from the MainActivity. We extract the extra data from the APP_DATA Bundle to refine the search:

public class SearchableActivity extends AppCompatActivity {
    public static final String JARGON = "com.example.searchinterface.jargon";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_searchable);

        handleIntent(getIntent());
    }

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

        handleIntent(intent);
    }

    private void handleIntent(Intent intent) {

        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            // use the query to search the data somehow

            Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
            if (appData != null) {
                boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
                // use the context data to refine our search
            }
        }
    }
}

现在,我们需要实现我们的MainActivity类.因此,我们增加菜单并配置SearchView元素.我们还需要设置SearchView.OnQueryTextListener并实现其方法,尤其是onQueryTextSubmit().当用户按下提交"按钮时将调用该方法,它包含将搜索上下文数据传递到SearchableActivity的主要逻辑. 最后,我们到达了主要答案部分.正如我所说的,有两种解决方案:

Now, we need to implement our MainActivity class. So, we inflate our menu and configure the SearchView element as well. We also need to set the SearchView.OnQueryTextListener and implement its methods, especially onQueryTextSubmit(). It is invoked when the user presses the submit button and it contains the main logic of passing the search context data to the SearchableActivity. Finally, we reached the main answer section. As I said, there are two solutions:

1.用Bundle extra创建意图并手动将其发送到SearchableActivity

1. Create an intent with Bundle extra and send it to the SearchableActivity manually;

这是MainActivity,其中包含所有必需的内容:

Here is the MainActivity with all necessary contents:

public class MainActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {
    private SearchView mSearchView;

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

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

        // associate searchable configuration with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        mSearchView.setSearchableInfo(searchManager.getSearchableInfo(
                new ComponentName(this, SearchableActivity.class)));

        mSearchView.setOnQueryTextListener(this);

        return true;
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        Intent searchIntent = new Intent(this, SearchableActivity.class);
        searchIntent.putExtra(SearchManager.QUERY, query);

        Bundle appData = new Bundle();
        appData.putBoolean(SearchableActivity.JARGON, true); // put extra data to Bundle
        searchIntent.putExtra(SearchManager.APP_DATA, appData); // pass the search context data
        searchIntent.setAction(Intent.ACTION_SEARCH);

        startActivity(searchIntent);

        return true; // we start the search activity manually
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        return false;
    }
}

感谢 https://stackoverflow.com/a/22184137/6411150 .

第二个解决方案也放在onQueryTextSubmit()中(但这不是必需的):

The second solution is also put in onQueryTextSubmit() (but it's not necessary):

2.创建搜索上下文数据Bundle并将其传递给SearchViewsetAppSearchData()方法.

2. Create search context data Bundle and pass it to the setAppSearchData() method of the SearchView.

因此,我们无需创建和传递整个搜索意图并启动相应的可搜索活动,系统将予以处理.

So, we don't need to create and pass the whole search intent and launch respective searchable activity, the system will take care of it.

这是另一个代码段:

/*
 You may need to suppress the "restrictedApi" error that you could possibly
 receive from this method "setAppSearchData(appData)".I had to
 I’m targetSdkVersion 26. I’m also using Android Studio 3 
 with the new gradle plugin, which might be causing this.

 If you’re not running Android Studio 3 you can simply put
 "//noinspection RestrictedApi" 
  right above the line: mSearchView.setAppSearchData(appData);
 */
@SuppressWarnings("RestrictedApi")
@Override
public boolean onQueryTextSubmit(String query) {
    Bundle appData = new Bundle();
    appData.putBoolean(SearchableActivity.JARGON, true); // put extra data to Bundle
    mSearchView.setAppSearchData(appData); // pass the search context data

    return false; // we do not need to start the search activity manually, the system does it for us 
}

感谢 https://stackoverflow.com/a/38295904/6411150 .

注意::仅支持库的SearchView(android.support.v7.widget.SearchView)版本包含setAppSearchData()方法,因此请注意.

Note: Only support library's version of SearchView (android.support.v7.widget.SearchView) contains the setAppSearchData() method, so be attentive.

这篇关于是否可以仅使用搜索小部件(SearchView)传递搜索上下文数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆