是否可以仅使用搜索小部件(SearchView)传递搜索上下文数据? [英] Is it possible to pass search context data using the Search Widget (SearchView) only?
问题描述
根据官方文档,提供搜索界面的两种方法:使用搜索对话框或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
并将其传递给SearchView
的setAppSearchData()
方法.
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屋!